从多个客户端同步接收 UDP 数据的正确方法是什么?
What is the correct method to receive UDP data from several clients synchronously?
我有 1 个服务器和几个(最多 20 个)客户端。所有客户端都在随机时间发送 UDP 数据报。每个数据报都很短(大约 10B),但我必须确保正确接收来自每个客户端的所有数据。
如果我让所有客户端发送数据报到同一个端口,客户端 B 在服务器从客户端 A 接收数据的确切时间发送数据报,服务器似乎会丢失来自客户端 A 的数据。
那么做这项工作的正确方法是什么?我需要为 20 个客户端中的每一个创建一个侦听器吗?
当您将 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(如果可以的话)
我有 1 个服务器和几个(最多 20 个)客户端。所有客户端都在随机时间发送 UDP 数据报。每个数据报都很短(大约 10B),但我必须确保正确接收来自每个客户端的所有数据。
如果我让所有客户端发送数据报到同一个端口,客户端 B 在服务器从客户端 A 接收数据的确切时间发送数据报,服务器似乎会丢失来自客户端 A 的数据。
那么做这项工作的正确方法是什么?我需要为 20 个客户端中的每一个创建一个侦听器吗?
当您将 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(如果可以的话)