代码之家  ›  专栏  ›  技术社区  ›  DarkLazar

聊天应用程序的Java nat遍历

  •  6
  • DarkLazar  · 技术社区  · 13 年前

    我正在尝试为我的网络课程创建一个java聊天应用程序。到目前为止,我一直在尝试连接到另一个路由器后面的人。我现在的项目是有一个客户端程序和一个服务器程序。客户端程序首先登录到服务器程序,服务器程序将他们的IP和端口记录在数据库中,然后服务器将他们的朋友列表及其IP和端口返回给他们。然后,客户端关闭与服务器的连接,并尝试使用服务器发回的信息连接到另一个客户端。到目前为止,我的程序只能连接到服务器并获得朋友的IP和端口,但当我使用这些值连接到另一个客户端时,我无法连接。

    socket = new Socket();
    socket.setReuseAddress(true);
    socket.setKeepAlive(true);
    socket.setSoLinger(true, 10);
    socket.bind(new InetSocketAddress(Port));
    socket.connect(new InetSocketAddress(host, SERVER_PORT));
    reusePort = socket.getLocalPort(); 
    

    上面是用于连接到服务器的java代码片段,下面是我在客户端所做的操作。

    ss = new ServerSocket(reusePort);
    

    因此,从技术上讲,现在我正在监听我用来连接服务器的同一端口,该端口已登录并可检索到另一个客户端,并且与我的ip和端口一起位于NAT表中。我不确定我遗漏了什么,也不确定是否有一些协议或我必须做的事情。我看过TCP和UDP打孔,但我不确定这是如何实际实现的,也不知道如何实现。

    如有任何建议,我们将不胜感激。

    2 回复  |  直到 13 年前
        1
  •  2
  •   Anil Vaitla    13 年前

    如果你想发送消息,你需要在任何充当服务器的设备(任何创建套接字服务器的设备)上设置端口转发。端口转发在路由器上完成。你无法连接到另一个客户端的原因是它们隐藏在路由器防火墙后面。他们对世界其他地方的地址实际上是路由器的地址,而不是他们物理计算机的地址。在他们的本地网络上,他们的地址与世界其他地方看到的地址不同,路由器根据地址转换表计算出需要将来自外部世界的哪些消息发送到客户端。

    考虑到您的体系结构,这意味着所有客户端都需要让他们的路由器进行端口转发,这当然是不可行的(想象一下gtalk或aim要求用户进行端口转发)。

    更常见的体系结构是让服务器将消息重新广播到连接的客户端,并维护表来查找谁与谁交谈。这样,就有一个需要静态ip(或端口转发)的服务器,所有用户都只是连接到服务器套接字并从中读取消息的客户端。

    有关描述第二种体系结构的实际代码,请参阅 http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html 然后,运行服务器代码的机器需要一个静态ip,或者如果它在路由器后面,则需要来自它正在侦听的端口的流量进行转发。

    因此,在服务器代码上,您将绑定到路由器分配的ip(在某个端口,比如5000,类似192.168.1.2)。然后转到路由器配置页面(可能是192.168.1.1,请参阅 http://www.wikihow.com/Port-Forward/Open-Ports-on-a-Linksys-Router ),并将端口5000转发到地址192.168.1.2。

        2
  •  2
  •   Rajat Charleston    9 年前

    交互式连接建立(ICE)协议结合了诸如STUN和TURN协议之类的各种NAT穿越实用程序,以便提供允许诸如SIP和XMPP之类的基于提供/应答的协议穿越NAT的强大机制。

    该项目提供了ICE协议的Java实现,SIP和XMPP应用程序都可以使用该协议。该项目还提供了诸如套接字共享和对伪TCP的支持等功能。

    ice4j由 Jitsi 社区

    ice4j

    推荐文章