Winsock UDP数据包被丢弃?包被、数据、Winsock、UDP

2023-09-07 12:43:05 作者:奈何桥上的守候

我们在 Windows 中有一个通过 UDP 设置的客户端/服务器通信系统.我们面临的问题是,当吞吐量增长时,数据包会被丢弃.我们怀疑这是由于 UDP 接收缓冲区不断被轮询导致缓冲区被阻塞并丢弃任何传入的数据包.读取这个缓冲区是否有可能导致传入的数据包被丢弃?如果是这样,纠正这个问题的选项是什么?该系统是用 C 编写的.如果这太模糊,请告诉我,我可以尝试提供更多信息.谢谢!

We have a client/server communication system over UDP setup in windows. The problem we are facing is that when the throughput grows, packets are getting dropped. We suspect that this is due to the UDP receive buffer which is continuously being polled causing the buffer to be blocked and dropping any incoming packets. Is it possible that reading this buffer will cause incoming packets to be dropped? If so, what are the options to correct this? The system is written in C. Please let me know if this is too vague and I can try to provide more info. Thanks!

推荐答案

Windows 套接字中的默认套接字缓冲区大小为 8k,即 8192 字节.使用 setsockopt Windows 函数来增加缓冲区(参考 SO_RCVBUF 选项).

The default socket buffer size in Windows sockets is 8k, or 8192 bytes. Use the setsockopt Windows function to increase the size of the buffer (refer to the SO_RCVBUF option).

但除此之外,如果您没有足够快地读取数据包,则增加接收缓冲区的大小只会延迟数据包再次被丢弃的时间.

But beyond that, increasing the size of your receive buffer will only delay the time until packets get dropped again if you are not reading the packets fast enough.

通常,这种情况需要两个线程.

Typically, you want two threads for this kind of situation.

第一个线程仅用于服务套接字.换句话说,线程的唯一目的是从套接字读取一个数据包,将其添加到某种适当同步的共享数据结构中,发出一个数据包已收到的信号,然后读取下一个数据包.

The first thread exists solely to service the socket. In other words, the thread's sole purpose is to read a packet from the socket, add it to some kind of properly-synchronized shared data structure, signal that a packet has been received, and then read the next packet.

存在第二个线程来处理接收到的数据包.它处于空闲状态,直到第一个线程表示已收到数据包.然后它从正确同步的共享数据结构中提取数据包并对其进行处理.然后等待再次发出信号.

The second thread exists to process the received packets. It sits idle until the first thread signals a packet has been received. It then pulls the packet from the properly-synchronized shared data structure and processes it. It then waits to be signaled again.

作为测试,请尝试缩短数据包的完整处理过程,并在每次收到数据包时向控制台(或文件)写入一条消息.如果您可以在不丢包的情况下成功完成此操作,那么将您的功能分解为接收"线程和处理"线程会有所帮助.

As a test, try short-circuiting the full processing of your packets and just write a message to the console (or a file) each time a packet has been received. If you can successfully do this without dropping packets, then breaking your functionality into a "receiving" thread and a "processing" thread will help.