单个 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..
}
上面的代码片段理论上可以处理任意数量的客户端,只需要一个线程即可。UDP 中没有会话通道的这种概念。
您可以(并且可能应该)复制接收到的数据并在此循环之外对其进行处理,以最大化利用的网络吞吐量。这是您必须独立于您选择的策略而做的事情。
没有理由认为上述实现的性能会明显低于其他方式。
- 创建多个套接字不会增加您的吞吐量。
- 背后的想法
setReuseAddress
是允许多个注册到同一个多播端点。不是为了增加吞吐量。
- 如果您认为接收和发送缓冲区可能会被流量溢出,则可以使用
DatagramSocket#setReceiveBufferSize
and增加接收和发送缓冲区DatagramSocket#setSendBufferSize
。