简体   繁体   English

用于聊天应用程序的Java nat遍历

[英]Java nat traversal for chat application

I am trying to create a java chat application for my networking class. 我正在尝试为我的网络类创建一个Java聊天应用程序。 As of right now I am stuck trying to connect to someone behind a different router. 截至目前,我被困在尝试连接到不同路由器后面的人。 The way I have my project right now is I have a client program and a server program. 我现在拥有项目的方式是我有一个客户端程序和一个服务器程序。 The client programs first logs into the server program which logs their IP and port in a database and then the server gives them back the list of their friends with their IPs and ports. 客户端程序首先登录到服务器程序,该程序将其IP和端口记录在数据库中,然后服务器通过其IP和端口向他们返回他们的朋友列表。 Then the client closes down the connection to the server and tries to connect to another client using the information the server sent back. 然后,客户端关闭与服务器的连接,并尝试使用服务器发回的信息连接到另一个客户端。 So far my program only works connecting to the server and getting the friends IP and port but when I use those values to connect to the other client I cant connect. 到目前为止,我的程序只能连接到服务器并获取朋友的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(); 

Above is a snippet of java code used to connect to the server then below is what i do on the client side. 上面是一段用于连接服务器的java代码,下面是我在客户端做的事情。

ss = new ServerSocket(reusePort);

So now technically I am listening on the same port I used to connect to the server with which is logged in and is retrievable to another client and is in the NAT table with my ip and port. 所以现在技术上我正在侦听我用来连接到登录的服务器的同一个端口,并且可以检索到另一个客户端,并且在我的ip和端口的NAT表中。 I am not sure what I am missing or if there is some protocol or something that I have to do. 我不确定我缺少什么,或者是否有某些协议或我需要做的事情。 I have looked at TCP and UDP hole punching but I am not sure how that is actually accomplished or how to implement it. 我已经看过TCP和UDP打孔但我不确定它是如何实现的或如何实现它。

Any suggestions would be appreciated. 任何建议,将不胜感激。

If you want to send a message you'll need to set up port forwarding on any device that acts as a server (any device which creates a socket server). 如果要发送消息,则需要在充当服务器的任何设备(任何创建套接字服务器的设备)上设置端口转发。 Port forwarding is done on the Router. 端口转发在路由器上完成。 The reason you cannot connect to the other client is because they are hidden behind their routers firewall. 您无法连接到其他客户端的原因是因为它们隐藏在路由器防火墙后面。 Their address to the rest of the world is actually the address of the router, not of their physical computer. 它们对世界其他地方的地址实际上是路由器的地址,而不是物理计算机的地址。 On their local network they have a different address then what the rest of the world sees, and the router figures out what messages from the outside world need to be sent to the client based on an address translation table. 在他们的本地网络上,他们拥有与世界其他地方看到的不同的地址,并且路由器根据地址转换表确定需要将来自外部世界的消息发送到客户端。

Given your architecture, this would mean that all clients need to have their routers doing port forwarding, which is of course unfeasible (imagine gtalk or aim requiring users to do port forwarding). 鉴于您的架构,这意味着所有客户端都需要让他们的路由器进行端口转发,这当然是不可行的(想象一下gtalk或目标需要用户进行端口转发)。

The more common architecture is to have the Server do the work of rebroadcasting messages to the connected clients and maintain tables to lookup whose talking with who. 更常见的体系结构是让服务器执行将消息重新广播到连接的客户端的工作,并维护表以查找与谁通话。 This way there is a single server which will need a static ip (or be port forwarded), and all users are simply clients which connect to the server socket and read messages from it. 这种方式有一个服务器需要一个静态IP(或端口转发),所有用户都只是连接到服务器套接字并从中读取消息的客户端。

For actual code describing the second architecture please see http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html . 有关描述第二个体系结构的实际代码,请参阅http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-c​​lient-server.html Then the machine which is running the server code either needs a static ip or if it is behind a router needs traffic from the port it is listening on to be forwarded. 然后运行服务器代码的机器需要静态IP,或者如果它在路由器后面,则需要来自正在侦听的端口的流量进行转发。

So on the server code you will bind to the ip assigned from your router (something like 192.168.1.2 at some port say 5000). 因此,在服务器代码上,您将绑定到从路由器分配的IP(类似于192.168.1.2在某个端口,例如5000)。 Then go to your routers configuration page (it may be 192.168.1.1 see http://www.wikihow.com/Port-Forward/Open-Ports-on-a-Linksys-Router ), and forward port 5000 to the address 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。

The Interactive Connectivity Establishment (ICE) protocol combines various NAT traversal utilities such as the STUN and TURN protocols in order to offer a powerful mechanism that allows Offer/Answer based protocols such as SIP and XMPP to traverse NATs. 交互式连接建立(ICE)协议结合了各种NAT遍历实用程序,例如STUN和TURN协议,以提供一种强大的机制,允许基于提供/应答的协议(如SIP和XMPP)遍历NAT。

This project provides a Java implementation of the ICE protocol that would be usable by both SIP and XMPP applications. 该项目提供了ICE协议的Java实现,SIP和XMPP应用程序都可以使用它。 The project also provides features such as socket sharing and support for Pseudo TCP. 该项目还提供了诸如套接字共享和对Pseudo TCP的支持等功能。

ice4j is maintained by the Jitsi community. ice4j由Jitsi社区维护。

ice4j ice4j

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM