如何在同一本地/src 地址上创建多个 UDP 数据报通道/流
Posted
技术标签:
【中文标题】如何在同一本地/src 地址上创建多个 UDP 数据报通道/流【英文标题】:how to create multiple UDP Datagram channels/streams on same local/src address 【发布时间】:2021-07-15 16:35:46 【问题描述】:我必须从服务器同一端口上的差异客户端接收数据。 为此,我想为每个客户端创建单独的通道并接收每个通道的数据。
我正在探索所有可用的设计方案。
选项 1:侦听单个套接字并处理来自各种设备的数据。
选项 2:在相同的 src 地址(在服务器中)上创建多个通道,并使用不同的远程地址(客户端),并使用 NIO 选择器来处理这些通道上的数据。
选项 1 似乎有点冒险,因为远程设备数量庞大。 而且我似乎无法实现选项 2。即使在绑定通道之前使用 setReuseAddress() API,我也会遇到绑定异常。
有人可以帮我吗?或者如果有更好的方法来设计这个。我已经探索了有关 *** 的其他问题,但我仍然无法正确理解它是否可行。
【问题讨论】:
这个问题应该被关闭,因为(1)没有代码可以显示 OP 已经尝试过什么并解释什么是行不通的,(2)OP 正在寻求替代方案,这将充其量只能导致自以为是的答案。 SO 不是一个讨论论坛,而是一个问答平台。因此,这个问题不属于现在的写法。请改进或完全删除它。 【参考方案1】:单个 UDP 套接字可以服务多个客户端。
由于 UDP 是一种无状态协议,您可以从所有这些客户端读取数据,而无需为每个客户端创建线程(或通道)。
int yourPort = // ...
try (DatagramSocket socket = new DatagramSocket(new InetSocketAddress("0.0.0.0", yourPort)))
byte[] buf = new byte[65535];
DatagramPacket packet = new DatagramPacket(buf, 0, buf.length);
while (socket.isBound() && !socket.isClosed())
// The packets received here are from all sources, not just a single source
socket.receive(packet);
// If we simply send that same packet, without modifying anything, it
// will echo the same content to whoever sent that packet
socket.send(packet);
catch (IOException e)
// probably a good idea to close/re-bind here..
理论上,上面的 sn-p 可以处理任意数量的客户端,只需要一个线程即可。 UDP 中没有会话通道的概念。
您可以(并且可能应该)复制接收到的数据并在此循环之外对其进行处理,以最大限度地利用网络吞吐量。这是您必须做的事情,与您选择的策略无关。
没有理由认为上述实现的性能会明显低于其他方式。
创建多个套接字不会增加您的吞吐量。
setReuseAddress
背后的想法是允许多个注册到同一个 multicast 端点。不是为了增加吞吐量。
如果您认为接收和发送缓冲区可能会被流量溢出,您可以使用DatagramSocket#setReceiveBufferSize
和DatagramSocket#setSendBufferSize
增加接收和发送缓冲区。
【讨论】:
以上是关于如何在同一本地/src 地址上创建多个 UDP 数据报通道/流的主要内容,如果未能解决你的问题,请参考以下文章