使用NAT将UDP数据包发送到IP

时间:2019-09-19 07:19:08

标签: java sockets networking udp

我有一台运行没有NAT的公共IP的服务器。它接收UDP数据包,我想将其发送到连接的每个客户端。

一个或多个客户端将支持NAT。

我已经阅读了有关UDP打孔的内容,但它似乎并不是我想要的。我不是要从客户端发送到客户端。我希望数据流来自客户端->服务器->所有客户端。

客户

// Init TCP Socket
connection = new Socket(connectionAddress, 54540);

// Create receive socket
DatagramSocket socketReceive = new DatagramSocket(54541);

服务器


// Receive socket
receiveAudioSocket = new DatagramSocket(54541);

// Thread to handle new received packets
ServerAudioReceiverWorker audioReceiverWorker = new ServerAudioReceiverWorker(receiveAudioSocket, this);
audioReceiverWorker.start();

// TCP Socket
serverSocket = new ServerSocket(54540);
System.out.println("Server has started");

这是我的客户端服务器的基本设置。

我希望,如果我将UDP数据包从客户端发送到服务器的公共IP。路由器会为客户端网络上的端口54541添加一个NAT规则,以接收从服务器发送回客户端的公共IP和端口54541的UDP数据包。这似乎并不起作用。

我猜这是因为分配给NAT规则的端口有一个特定端口,用于向公共IP请求以本地IP为目标。我不确定如何找到服务器应将每个客户端发送数据包的端口。

我是否需要使用UPnP打开客户端网络上的端口,并让服务器知道要将数据包发送到哪个端口。

1 个答案:

答案 0 :(得分:1)

NAT要求NAT路由器后面的客户端首先启动与外部服务器的连接,以便NAT路由器可以为地址和端口转换创建状态。来自服务器的答复必须与状态完全匹配,否则NAT路由器将无法进行回译。

这意味着:

  • 您必须在客户端中使用相同的套接字进行发送和接收,即,您不能期望像当前那样在其他端口上返回答复。
  • 服务器必须将消息发送到客户端用作与服务器联系的源的完全相同的IP和端口,并且必须从客户端用作目标的完全相同的IP和端口发送消息。通过使用服务器上的相同套接字来完成。
  • 无法将消息发送到最近未联系服务器的客户端,因为在这种情况下,客户端NAT路由器中没有匹配状态(一段时间后过期)。