假设我有两台电脑。
他们通过ice4j
了解公共和私人IP。
一个客户端正在侦听,另一个发送一些字符串。
我希望通过UPD打孔来实现这一点:
Let A be the client requesting the connection
Let B be the client that is responding to the request
Let S be the ice4j STUN server that they contact to initiate the connection
--
A sends a connection request to S
S responds with B's IP and port info, and sends A's IP and port info to B
A sends a UDP packet to B, which B's router firewall drops but it still
punches a hole in A's own firewall where B can connect
B sends a UDP packet to A, that both punches a hole in their own firewall,
and reaches A through the hole that they punched in their own firewall
A and B can now communicate through their established connection without
the help of S
如果你考虑到双NAT也会很好。
您可以使用STUN来发现IP和端口,但您必须编写自己的代码,通过keepalive
技术将IP:端口发送到您的服务器。
一旦一个客户端通过服务器上的唯一ID识别另一个客户端,它将被提供另一个客户端IP:端口信息到UDP打孔它需要发送和接收的数据。
有一个库出现在地平线上为java检查出来:
https://github.com/htwg/UCE#readme
答案 0 :(得分:10)
您的问题非常广泛 - 我无法提供示例,但以下链接可能有所帮助(规格,库,样本等):
答案 1 :(得分:6)
您的问题与Java无关。如果您知道如何打开UDP连接,那就足够了。阅读以下link的内容。不要害怕标题,它也涵盖UDP。其余的只是Java编码。
P.S。:在您的方案中,缺少一步。 A和B都必须与S打开连接,因为S需要告诉B A正试图到达它。如果B没有与S的开放连接,则A和B无法开始一起通信。
<强>更新强>
Jason的回答包含有关NAT遍历的错误和疯狂猜测。人们应该阅读Saikat Guha (mpi-sws.org/~francis/imc05-tcpnat.pdf)所做的工作来真正理解这件事。维基百科的锥形分类完全过时且具有误导性。
答案 2 :(得分:6)
STUN基本上如下工作:防火墙后面的客户端连接到防火墙外的STUN服务器。 STUN服务器检查从客户端收到的数据包,并向客户端发送一个响应,其中包含STUN服务器看到的客户端IP和端口。
这就是防火墙后面的客户端发现自己的外部IP和端口的方式。据我所知,STUN服务器通常不会将地址信息从一个客户端传递到另一个客户端。
当防火墙已经对信令流量开放时,通常STUN用于通过防火墙设置媒体流 - 例如在VoIP中:客户端联系STUN服务器以发现自己的外部IP和UDP流量端口,然后将其信令请求(SIP INVITE或其他)发送到众所周知的开放端口上的其他客户端 - 包括其外部UDP地址信息在有效载荷(SDP或其他)中。因此,通常需要通过开放端口可访问一个客户端以用于发送对等通信的信令。