Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过NAT的P2P即时通信_Java_Sockets_Client Server_P2p - Fatal编程技术网

Java 通过NAT的P2P即时通信

Java 通过NAT的P2P即时通信,java,sockets,client-server,p2p,Java,Sockets,Client Server,P2p,我正在尝试建立一个P2P即时消息系统,虽然我还没有解决这个问题,但如果客户端在本地LAN上支持NAT(请阅读:Everyone),我希望我会遇到一些问题 让我解释一下算法,你就会明白我的意思了。有三个组件:一个服务器和两个客户机-客户机Alice希望启动与客户机Bob的聊天。服务器只跟踪谁在线,但实际对话不会通过服务器进行(为了客户的隐私) 因此,Alice和Bob都登录到服务器-从临时端口连接到服务器的静态侦听端口。它们告诉服务器它们正在监听哪个静态端口以接收传入的聊天请求。Alice询问服务

我正在尝试建立一个P2P即时消息系统,虽然我还没有解决这个问题,但如果客户端在本地LAN上支持NAT(请阅读:Everyone),我希望我会遇到一些问题

让我解释一下算法,你就会明白我的意思了。有三个组件:一个服务器和两个客户机-客户机Alice希望启动与客户机Bob的聊天。服务器只跟踪谁在线,但实际对话不会通过服务器进行(为了客户的隐私)

因此,Alice和Bob都登录到服务器-从临时端口连接到服务器的静态侦听端口。它们告诉服务器它们正在监听哪个静态端口以接收传入的聊天请求。Alice询问服务器如何与Bob联系。服务器使用IP地址和侦听端口等进行响应。Alice将该IP地址和端口上的请求发送给Bob,以建立连接。希望这是有道理的

如果Bob支持NAT,那么确保他可以与服务器对话,因为他是启动通信的人。但是Alice的请求不会传到他那里,因为他正在监听的端口的NAT关系还没有建立,因为Alice的IP地址发出了聊天请求

有人知道有什么黑魔法可以让这一切发生吗?这不是问题吗?发展还不远,我还没有真正遇到这个问题

显而易见,我不想让最终用户为其侦听端口配置端口转发


对于前面提到的黑魔法,客户端和服务器都是java的,但我通常只关注算法(如果可能的话)

没有黑魔法。如果两个客户端都支持NAT,则消息必须经过第三方(服务器)。 我会考虑使用这样的架构来进行所有的通信,如果只是关于文本消息(如果隐私是一个问题,你可以想到某种加密)。服务器(或多个服务器)的负载会更大,但架构会更简单(在某些情况下更可靠)。例如,如果Alice向Bob发送消息,而Bob有一些网络问题,服务器可以排队并保留消息一段时间,然后再发送(即使Alice脱机)。另一件事是会议(小组)聊天。仅用P2P处理它更具挑战性(但可能非常有趣)。但是如果所有的客户都支持NAT,你就会遇到同样的问题。 我还强烈建议为所有传输和接收的消息(来自客户端和服务器)实现应用程序级确认机制。TCP/IP等协议不够可靠。

请检查

大多数P2P框架,如Java中的JXTA,都使用中继服务器的原理

假设A想连接到B,B在防火墙后面

- both A and B establish ** outbound ** synchronous (or full duplex/websockets) connections to Relay Server R
- A signals to R that it wants to transmit data to B
- R 'binds' the inbound connection from A to the outbound connection to B (the synchronous HTTP response to B for instance)
- A sends data to R which is relayed to B
这里的关键是,所有的连接都是建立在出站(通常使用友好的防火墙协议,如在知名端口上的HTTP)上的


当你使用分布式继电器时,事情显然会变得更复杂一些;然后,您需要“路由器”,通过中继维护到各个对等方的路由,中继依赖分布式哈希映射(DHT)来维护信息。

看看jabber甚至skype等聊天系统就知道了。您必须配置端口转发、使用代理或通常打开的回退端口,如80。。。