AS3 + Java 端口号低于 1024 的 Socket 连接
原文:AS3 + Java: Socket connections to ports below 1024
翻译:dreamana.com
如今在很多人开始试验 AS3 的 Socket 类,在此之前我常看到有人说不能连接低于 1024 的端口。其实可以用一个特殊的 socket server 给 Flash Player 返回一个 cross domain policy 信息来让它连接上的,这就像在你的 Web 服务器上放置一个 cross-domain-policy 文件一样,只需多花一点点精力。
连接低于 1024 的端口会带来一些有趣的可能,例如开发能绕过防火墙通过 80 端口的多用户应用程序,编写你自己的电子邮件客户端、FTP 客户端等等网络客户端(这都不需要监听进来的连接的,所以就别想在 Flash 里 P2P 了)。Joa Ebert 已经写了个 Flash IRC 客户端 的例子。你也可以自己写一个代理来连接某服务器的某端口 …
下面是使 AS3 Socket 和 XMLSocket 连接一个低端口的方法,如网页服务器 80 端口。
AS3 commands
当你调用 AS3 的 Socket 类的 connect 方法的时候:
Actionscript:
socket = new Socket();
socket.connect("localhost", 80);
…Flash Player 会悄悄打开一个 Socket (上面的例子是 80 端口) 并发送出如下字符序列:
XML:
<policy-file-request/>
如果服务器回应一个 xml 文件格式的 policy 字符串,Flash Player 就会打开一个真正的 Socket 并把 Event.CONNECT 事件撤掉。要是没有 policy 字符串返回将会连接失败。
XML:
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" to-ports="80" />
</cross-domain-policy>
现在你可能不想编辑你的 Web 服务器的源代码来让它回应 Flash Player 的 policy-请求。幸好 AS3 有一个命令可以使 Flash 连接到另一个端口去寻找 policy:
Actionscript: Security.loadPolicyFile(“xmlsocket://localhost:1008”);
这会使 Flash Player 在 1008 端口打开一个 Socket,发送一个 policy-请求并读取 policy-文件。若允许连接则毫不延误地在 80 端口打开所期望的 Socket 连接。
要注意的是,在低于 1024 端口读取 policy-文件只能够创建低于 1024 的连接。如果你的 policy-文件放到在某个大于 1024 的端口(譬如 8008)上服务,是不可以创建 1024 以下的连接的,就算 policy-文件这样写。
奇怪的是, Adobe’s DTD 定义 policy file 的结构 并没有提到 to-ports 属性,然而 Flash Player 却一定会读取它。
Java socket server
我写了一个简单的 Java 类,启动后就是一个 policy 服务器。默认是监听在 1008 端口,允许连接任意端口。这仅为了便于测试,公开运行时一定要更改。
你可以在这里 下载源代码 或者 下载可运行的 jar 文件 。
你只需安装了 Java-Runtime-Environment (可能你已经有了)并在命令行上输入 java -jar policyserver.jar
Flex example client
我还写了一个小例子,一个连接本地 Web 服务器的 AS/Flex 应用程序,发送一个 HTTP GET 命令并读取从 Web 服务器返回包含 HTTP 头部的信息。你可以当它是浏览器 ;) - 可惜它只能让你连接到带有 policy 服务器运行着的服务器。
你可以在这里 下载源代码 将它导入一个 Flex project 中并将 WebReader.as 设为 Default Application 即可。
Update 2011/07/28 补充:
843 是默认端口。如果你的服务端在接收到连接请求时候能够在 843 端口输出 cross-domain-policy,那么就不需要 Flash 客户端里面额外写代码,它会自动完成被授权访问的操作。