如何为客户端数组发送 UDP 消息 (java)



我的问题是,如何为一个数组发送UDP消息,其中包含在TCP套接字中连接到服务器的IP列表?

我做的代码(只是服务器应用程序,发送部分):

DatagramSocket socketCliente = new DatagramSocket();       
InetAddress[] IP = InetAddress.getAllByName(socketLigacao.getInetAddress().getHostAddress());   
byte[] enviaMensagem = new byte[1024];        
enviaMensagem = mensagemCliente.getBytes();
for (int i = 0; i < IP.length; i++){
DatagramPacket enviaPacote = new DatagramPacket(enviaMensagem, enviaMensagem.length, IP[i],     3790);
socketCliente.send(enviaPacote)

所做的代码只是在本地主机中工作(在 netbeans 输出中测试),当我在不同的机器上运行时,客户端不显示任何输出,我确定问题出在我发布的这部分代码中......

任何帮助将不胜感激,如果tou需要更多信息,请告诉我。

干杯!

你的代码是正确的。问题出在网络上。

在当前代码中,您尝试将 UDP 数据包发送到具有相应 IP 地址和端口 (3790) 的多个客户端。

当您在本地主机上时,这有效,因为客户端 IP 和端口未映射到不同的 IP 和端口。当您在本地主机上时,您只需使用本地 IP 和计算机的本地端口即可。

在实际场景中,情况有所不同。客户端连接到路由器,准确地说是互联网和客户端之间的防火墙。

路由器创建映射以访问客户端计算机。客户端的本地 IP 和端口映射到外部 IP(路由器通过 ISP 获取的 IP)和外部端口(标识客户端进程)。本地 IP 和端口由路由器分配给客户端。这称为网络地址转换 (NAT)。

路由器维护一个路由表,用于将数据包从源路由到目标。

默认情况下,它允许所有 TCP 数据包在成功连接后进入或离开系统。

但是对于UDP数据包,路由器仅允许传出数据包(从网络到其他网络的数据包)并阻止传入数据包。

它只允许来自这些地址的 UDP 数据包进入网络,客户端之前已将数据包发送到该网络(因为发送数据包会在路由器表中创建一个条目)。换句话说,路由器仅允许其 IP 和端口条目在路由表中可用的数据包。

示例

考虑连接到路由器的客户端计算机"A"。让路由器具有 ISP 提供的外部 IP w.x.y.z。当客户端启动UDP数据包,让路由器为其分配一个外部端口,例如55000. 要到达客户端计算机,路由器将为其分配一个本地 IP,例如 192.168.1.62 和某个端口 3790(或由客户端定义)过程)。路由器创建此内部或本地 IP 的映射和端口分别到外部 IP 和端口。这可以是一个可能的映射:

External IP:port    <-------------->    Local IP:port
   w.x.y.z:55000    <-------------->    192.168.1.62:3790

这取决于路由器使用的 NAT 方案类型。所以,为了让客户端从网络,另一端的机器必须将数据包发送到路由器分配的客户端的外部 IP 和端口,而启动 UDP 数据包。然后路由器会将其转发到客户端的本地 IP 和端口。

在您的情况下,您正在发送数据包,但这些数据包被互联网和客户端之间的路由器阻止。您需要将数据包发送到客户端的外部 IP 和端口。

为此,您需要实现 UDP 打孔。尽管它不保证适用于所有类型的 NAT。

或者更好地说,请阅读更多关于网络条件的信息,关于这些映射是如何在路由器中完成的,等等。

以下是一些来源:

网络地址转换

UDP 打孔

RFC 4787 NAT 行为要求 UDP

RFC 5128 跨 NAT 的 P2P

最新更新