【问题标题】:Connect two clients using AS3 ServerSocket and Socket使用 AS3 ServerSocket 和 Socket 连接两个客户端
【发布时间】:2015-05-03 16:48:19
【问题描述】:

我正在尝试使用 AIR 创建一个简单的应用程序,该应用程序使用套接字将两个客户端相互连接。

我知道ServerSocket类可以用来监听TCP连接,你可以使用Socket类发出TCP连接请求。事实上,一个连接到自身或另一个测试应用程序的简单测试应用程序在 localhost 上运行良好:

服务器类:

private var server:ServerSocket;
private var clients:Vector.<Socket> = new Vector.<Socket>;

public function create() {
    server = new ServerSocket();
    server.bind(8888);
    server.addEventListener(ServerSocketConnectEvent.CONNECT, serverConnectHandler);
    server.listen();
}

private function serverConnectHandler(e:ServerSocketConnectEvent):void {
    var socket:Socket = e.socket;
    clients.push(socket);
    socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
}

private function socketDataHandler(e:ProgressEvent):void {
    var socket:Socket = e.currentTarget as Socket;
    var data:Object = socket.readObject();
    trace("Data received:", data);
}

public function send(data:Object):void {
    for each(var client:Socket in clients){
        client.writeObject(data);
        client.flush();
    }
}

客户端类:

private var socket:Socket;

public function create() {
    socket = new Socket();
    socket.addEventListener(Event.CONNECT, connectHandler);
    socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
}

public function connect(address:String):void {
    socket.connect(address, 8888);
}

private function connectHandler(e:Event):void {
    trace(e);
}

private function socketDataHandler(e:ProgressEvent):void {
    var data:Object = socket.readObject();
    trace("Data received:", data);
}

public function send(data:Object):void {
    socket.writeObject(data);
    socket.flush();
}

如果我connect() 来寻址“localhost”,则上述内容适用于单台机器。

我有点迷茫的是如何在两台机器之间建立实际连接,这两台机器都连接到互联网,但不在同一个网络上。由于两台机器(可能)都在路由器后面,我假设我需要路由器的 IP 地址,并且路由器必须知道将我的应用程序所需的端口(上面的 8888)转发到运行 ServerSocket? 的机器上。可以从 AIR 建立此端口转发吗? AIR 能否收集到当前机器建立连接所需的地址和端口?

换句话说,如果一台机器没有直接连接到互联网(它在路由器后面),因此没有公共IP地址,另一台机器如何连接到它?显然,这可以通过机器连接的路由器的必要公共 IP 地址和路由器 [端口?] 转发到机器来完成,但我不清楚如何从 AIR 进行设置,甚至可以在 AIR 中进行设置.

例如,NetworkInfo/findInterfaces() 返回 LAN 地址列表,但不返回 who.is 上显示的公共 IP 地址。

我可以使用公共域上的 Apache 服务器在客户端之间共享地址信息,但我希望让客户端建立直接 p2p 连接。

谢谢!

【问题讨论】:

  • 我从事过这样的工作,但您的意思是:“AIR 能否收集当前机器建立连接所需的地址和端口”?因为当一个 AIR 应用连接到其他应用时,它不需要知道自己的机器地址!
  • 嗨。客户端需要为其他客户端共享自己的地址和端口。我可以通过 HTTP 服务器(PHP + SQLite)分享这些信息。但是,如果客户端位于路由器后面,来自NetworkInfo/findInterfaces() 的地址似乎不会显示公共 IP 地址,就像您在 who.is 上看到的那样。那么如何让路由器后面的两台机器连接起来呢?
  • 我补充了一点说明。
  • 对于公网IP,需要服务端服务。对于客户端连接,我认为在所有情况下,您都需要一台服务器。您的客户端连接到它,然后它可以获取其他客户端地址进行连接。当然,在使用服务器时,客户端不需要知道它的地址,因为服务器可以得到它。
  • 我还是一头雾水。我有一个 Apache 服务器,但“服务器端服务”是做什么的?我可以共享客户端的地址,但这些地址只会让客户端与其他客户端连接的路由器一样远。

标签: actionscript-3 sockets tcp air


【解决方案1】:

我知道这个问题已经有 2 年历史了,但是对于那些在未来摸不着头脑的人:

我刚刚让你的代码在我身上工作;您需要在服务器的计算机上进行端口转发。基本上,让您的路由器将任何传入的 8888 TCP 流量指向运行服务器的计算机(让它指向计算机的 8888 端口)。

客户端不需要对其进行端口转发,因为当服务器回复时,客户端的路由器将其视为“响应”并允许数据包通过。

除此之外,只需将客户端连接到服务器(路由器)的公共 IP,您可以通过 here 找到它。

【讨论】:

  • 过去的爆炸。 :) 你是如何设置服务器的端口转发的?手动配置您的路由器,还是通过 AIR 应用程序本身?问题是许多 p2p 应用程序不需要你弄乱你的路由器,我从来没有完全弄清楚他们是如何做到这一点的,以及你是否可以从 AIR 应用程序中做到这一点。
  • @Aaron 我必须在路由器上设置它。虽然我不是专家,但我认为您所指的可能涉及 UDP/TCP 打孔,这是我还没有进入的兔子洞。根据我的经验,唯一合理的解决方案是在服务器上转发端口。如果您知道如何让 AIR 应用程序在不干扰路由器的情况下执行此操作,请告诉我!但据我所知,开始工作真的很复杂。
  • @Aaron 我的回答有帮助吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-31
相关资源
最近更新 更多