C++ UDP 套接字数据包排队
我使用相同的 UDP 套接字来发送和接收数据。我想知道 DGRAM 套接字的数据包排队是否已经存在,或者我们是否必须单独处理它。
如果用户代码必须处理排队,那么它是如何完成的?我们是否有单独的线程来接收套接字并将数据包放入reciver_queue中并从另一个sending_queue发送到sendto?
示例代码绝对很棒。感谢您的帮助。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有一个数据包队列。然而,当数据包队列已满时,UDP 数据包开始被丢弃。当它们被丢弃时,它们将永远丢失,因此请确保继续读取数据!
There is a packet queue. However when the packet queue is filled then UDP packets start getting discarded. When they are discarded they are lost forever so make sure you keep reading data!
正如 Goz 所指出的,存在一个数据包队列。实际上,在以应用程序结束的整个管道的各个位置都有不止一个。网卡上通常有一些缓冲区,然后还有一些由内核管理。通常可以使用setsockopt()为各个套接字调整内核缓冲区的大小。
正如 Goz 已经指出的那样,UDP 数据包可能会在发送给您的途中丢失,或者它们可能会以不同的顺序到达。如果您需要可靠性和排序,并且不能使用 TCP,则必须实现某种在 UDP 之上提供这两种功能的协议,例如 滑动窗口协议。
As Goz has noted, there is a packet queue. There is more than one, actually, at various places of the whole pipeline that ends in your application. There are usually some buffers on the NIC, then there are some managed by the kernel. The kernel buffers often can be sized for individual sockets using setsockopt().
As Goz has already noted, UDP packets can be lost on their way to you, or they can arive in different order. If you need both realiability and ordering and if you cannot use TCP instead, you will have to implement some kind of protocol that will provide both atop UDP, e.g. sliding window protocol.
对于 UDP,实际上只有接收套接字缓冲区。虽然有 SO_SNDBUF 套接字选项,但提供的值只是数据报大小的上限。出站数据报要么整个提供给硬件,要么以片段形式(如果它比 MTU 更大)提供给硬件,或者被丢弃。硬件通常有一些环形缓冲区,但这实际上与 DMA 有关,与用户态应用程序无关。
应用程序中数据包排队最直接的技术是循环缓冲区 - 使其变大足以满足正常使用,在高峰期间丢失一些数据包。当然还有其他方法。
With UDP there's actually only the receive socket buffer. While there is
SO_SNDBUF
socket option, the value supplied is just the upper limit for the datagram size. The outbound datagram is either given to the hardware in whole, or in fragments (if it's bigger then the MTU), or discarded. The hardware usually have some ring buffers, but that really has to do with DMA and of no concern to userland apps.The most straightforward technique for packet queueing in the application is, again, a circular buffer - make it large enough for normal usage, lose some packets during heavy spikes. Surely there are other approaches.