如何为一组客户端发送 UDP 消息 (java) [英] How to send an UDP message for an array of clients (java)

查看:30
本文介绍了如何为一组客户端发送 UDP 消息 (java)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

感谢任何帮助,如果您需要更多信息,请告诉我.

干杯!

解决方案

您的代码是正确的.网络问题.

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

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

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

路由器创建一个映射来访问客户端机器.客户端的本地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 和端口.这可以是一个可能的映射:

外部IP:端口<-------------->本地IP:端口w.x.y.z:55000 <-------------->192.168.1.62:3790

<块引用>

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

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

您需要为此实施UDP 打孔.虽然它不保证适用于所有类型的 NAT.

<块引用>

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

以下是一些来源:

网络地址转换

UDP 打孔

RFC 4787 NAT 行为要求 UDP

跨 NAT 的 RFC 5128 P2P

My question is how do i send an UDP message for an array with a list of IP's connected to the server in TCP sockets?

the code i did (just the server application, the sending part):

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)

The code i did are just working in localhost (tested in netbeans output), when I run in different machines the client don't show any output, and i'm sure that the problem is in this part of code that i posted...

Any help would be apreciated, if tou need any more information please let me know.

Cheers!

解决方案

Your code is correct. The problem is with the networking.

In your current code, you are trying to send UDP packets to several clients at their corresponding IP addresses and a port (3790).

This worked while you were on localhost as the client IP and port were not mapped to a different one. While you were on the local host, you simply played with the local IP and a local port to the machine.

In practical scenario, things are different. The clients are connected to a router, and precisely a firewall between the internet and your client.

The router creates a mapping to reach out the client machine. The local IP and port of the client are mapped to the external IP (the IP which the router gets by the ISP) and an external port(which identifies the client process). The local IP and port are allotted by the router to the client. This is called Network Address Translation(NAT).

The router maintains a routing table to route the packets from source to destination.

By default, it allows all TCP packets to enter or leave the system after a successful connection.

But in case of UDP packets, the router allows only outgoing packets(packets leaving the network to some other network) and blocks the incoming packet.

It allows UDP packets only from those address to enter the network, to which a packet was sent by the client earlier(as sending a packet creates an entry in the router table). In other words, the router allows only those packets whose IP and port entry is available in the routing table.

Example:

Consider a client machine "A" connected to a router. Let the router has an external IP w.x.y.z provided by the ISP. When the client initiates a UDP packet, let the router assign it an external port say 55000. To reach the client machine, the router will allot it a local IP say 192.168.1.62 and some port 3790(or define by the client process). The router creates a mapping of this internal or local IP and port to the external IP and port respectively. This can be a possible mappding:

External IP:port    <-------------->    Local IP:port

   w.x.y.z:55000    <-------------->    192.168.1.62:3790

This depends on the type of NAT scheme the router uses. So, in order to let the clients receive packets from some machine external to the network, the machine on the other side must send the packets to the external IP and port of the client allotted by the router while initiating the UDP packet. The router will then forward it to the local IP and port of the client.

In your case, you are sending packets but these packets are blocked by the router which comes in between the internet and the client. You need to send packets to the external IP and port of the client.

You will need to implement UDP hole punching for this. Although it does not guarantee to work on all types of NAT.

Or better to say that please read more about networking conditions, about how these mappings are done in the router, etc.

Here are some of the sources:

Network Address Translation

UDP Hole Punching

RFC 4787 NAT Behavioral Requirements UDP

RFC 5128 P2P across NAT

这篇关于如何为一组客户端发送 UDP 消息 (java)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆