Dar*_*zar 6 java sockets chat nat
我正在尝试为我的网络类创建一个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();
Run Code Online (Sandbox Code Playgroud)
上面是一段用于连接服务器的java代码,下面是我在客户端做的事情.
ss = new ServerSocket(reusePort);
Run Code Online (Sandbox Code Playgroud)
所以现在技术上我正在侦听我用来连接到登录的服务器的同一个端口,并且可以检索到另一个客户端,并且在我的ip和端口的NAT表中.我不确定我缺少什么,或者是否有某些协议或我需要做的事情.我已经看过TCP和UDP打孔但我不确定它是如何实现的或如何实现它.
任何建议,将不胜感激.
如果要发送消息,则需要在充当服务器的任何设备(创建套接字服务器的任何设备)上设置端口转发。端口转发是在路由器上完成的。您无法连接到其他客户端的原因是它们隐藏在路由器防火墙后面。他们对世界其他地方的地址实际上是路由器的地址,而不是他们的物理计算机的地址。在他们的本地网络上,他们有一个与世界其他地方所看到的地址不同的地址,路由器根据地址转换表找出需要将来自外界的哪些消息发送到客户端。
鉴于您的架构,这意味着所有客户端都需要让其路由器进行端口转发,这当然是不可行的(想象一下 gtalk 或 goal 要求用户进行端口转发)。
更常见的架构是让服务器完成向连接的客户端重新广播消息的工作,并维护表来查找谁与谁通话。这样,就有一个需要静态 IP(或端口转发)的服务器,并且所有用户都只是连接到服务器套接字并从中读取消息的客户端。
有关描述第二种架构的实际代码,请参阅http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-c lient-server.html 。那么运行服务器代码的机器要么需要一个静态 IP,要么如果它位于路由器后面,则需要来自它正在侦听的端口的流量进行转发。
因此,在服务器代码中,您将绑定到从路由器分配的 IP(例如 192.168.1.2,某个端口为 5000)。然后转到您的路由器配置页面(可能是 192.168.1.1,请参阅http://www.wikihow.com/Port-Forward/Open-Ports-on-a-Linksys-Router),并将端口 5000 转发到地址 192.168 .1.2.