【问题标题】:What is the correct method to receive UDP data from several clients synchronously?从多个客户端同步接收 UDP 数据的正确方法是什么?
【发布时间】:2017-04-06 12:06:01
【问题描述】:
我有 1 台服务器和多个(最多 20 个)客户端。所有客户端都在随机时间发送 UDP 数据报。每个数据报都很短(大约 10B),但我必须确保正确接收来自每个客户端的所有数据。
如果我让所有客户端将数据报发送到同一个端口,而客户端 B 在服务器从客户端 A 接收数据的确切时间发送数据报,那么服务器似乎会丢失来自客户端 A 的数据。
那么完成这项工作的正确方法是什么?我需要为 20 个客户端中的每一个创建一个侦听器吗?
【问题讨论】:
标签:
udp
client-server
listener
【解决方案1】:
当您将 UDP 套接字绑定到端口时,网络堆栈将为您分配有限数量的传入 UDP 数据包缓冲区,以便(假设您以相对及时的方式调用 recv())没有传入数据包应该迷路了。
如果您想在终端中查看缓冲区大小,可以查看:
/proc/sys/net/core/rmem_default for recv
和
/proc/sys/net/core/wmem_default for send
我认为 Linux 上的默认缓冲区大小是 131071B。
在 Linux 上,您可以通过(以 root 身份)更改 UDP 缓冲区大小(例如更改为 26214400):
sysctl -w net.core.rmem_max=26214400
您也可以通过将此行添加到 /etc/sysctl.conf 来使其永久化:
net.core.rmem_max=26214400
由于每个数据包只有10B,应该没有问题。
如果您仍然担心数据包丢失,您可以实现一个协议,让您的客户端等待来自服务器的 ACK,否则它将重新发送。许多协议都使用这样的功能,但这只有在时间允许的情况下才有可能。例如在流数据中它没有用处,因为没有时间重新发送。
或者考虑使用 tcp(如果可以的话)