微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在相同的本地/src 地址上创建多个 UDP 数据报通道/流

如何解决如何在相同的本地/src 地址上创建多个 UDP 数据报通道/流

我必须从服务器的同一端口上的不同客户端接收数据。 为此,我想为每个客户端创建单独的通道并接收每个客户端的数据。

我正在探索所有可用的选项来设计它。

选项 1:侦听单个套接字并处理来自各种设备的数据。

选项 2:在相同的 src 地址(在服务器中)使用不同的远程地址(客户端)创建多个通道,并使用 NIO 选择器来处理这些通道上的数据。

选项 1 似乎有点冒险,因为远程设备数量庞大。 而且我似乎无法实现选项 2。即使我在绑定通道之前使用 setReuseAddress() API,我也会收到绑定异常。

有人可以帮我吗?或者如果有更好的方法来设计它。我已经探索了有关 stackoverflow 的其他问题,但我仍然无法正确理解它是否可行。

解决方法

单个 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,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..
}

上面的代码段理论上可以处理任意数量的客户端,只需要一个线程来完成。 UDP 中没有会话通道的概念。

您可以(并且可能应该)复制接收到的数据并在此循环之外对其进行处理,以最大限度地利用网络吞吐量。这是您必须独立于您选择的策略而做的事情。

没有理由认为上述实现的性能会明显低于其他方式。


  • 创建多个套接字不会增加您的吞吐量。
  • setReuseAddress 背后的想法是允许多个注册到同一个多播端点。不是为了增加吞吐量。
  • 如果您认为接收和发送缓冲区可能会被流量溢出,则可以使用 DatagramSocket#setReceiveBufferSizeDatagramSocket#setSendBufferSize 增加接收和发送缓冲区。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。