Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 通过单个套接字发送的UDP数据包是否保证按顺序发送?_Linux_Sockets_Network Programming_Udp_Posix - Fatal编程技术网

Linux 通过单个套接字发送的UDP数据包是否保证按顺序发送?

Linux 通过单个套接字发送的UDP数据包是否保证按顺序发送?,linux,sockets,network-programming,udp,posix,Linux,Sockets,Network Programming,Udp,Posix,我意识到依靠UDP协议来提供任何排序保证都不是一个好主意,应该改用TCP。请避免回答建议我使用TCP的问题。 我正在调试一些遗留的网络代码,想知道套接字接口提供的订购保证是什么。我的设置包括一个运行Debian的linux机器,通过直接以太网电缆与嵌入式设备进行对话。嵌入式设备无法容纳整个TCP堆栈,即使它容纳了,遗留堆栈也太旧,无法重构 具体地说,如果我有一个配置了默认单线程的NIC,并且我使用单线程通过一个套接字发送数据包,并且它们都具有相同的功能,那么在这些情况下,我是否可以保证所有数据包

我意识到依靠UDP协议来提供任何排序保证都不是一个好主意,应该改用TCP。请避免回答建议我使用TCP的问题。

我正在调试一些遗留的网络代码,想知道套接字接口提供的订购保证是什么。我的设置包括一个运行Debian的linux机器,通过直接以太网电缆与嵌入式设备进行对话。嵌入式设备无法容纳整个TCP堆栈,即使它容纳了,遗留堆栈也太旧,无法重构

具体地说,如果我有一个配置了默认单线程的NIC,并且我使用单线程通过一个套接字发送数据包,并且它们都具有相同的功能,那么在这些情况下,我是否可以保证所有数据包都将按照发送顺序通过线路发送

这是我在实践中观察到的行为,但我还没有找到任何标准、POSIX或其他方式来保证这种行为,我想确保在我上面列出的环境和假设下,这实际上是受支持的行为

相反,如果我通过两个单独的套接字发送数据包,我会发现它们不是按照我从应用程序代码发送它们的相同顺序通过NIC发送的。很明显,内核保留对通过单独套接字发送的数据包重新排序的权利,但在使用单个套接字时不这样做


据我所知,在套接字上调用
send()
,将数据包同步地放入NIC的相应队列中。队列的存在向我暗示了顺序的概念(否则列表将是数据结构更合适的名称)。无论是否存在此类订购保证,我都对某种文档或说明感兴趣。

对于这种行为没有保证,因为在一般情况下,它与用户207421提到的无关。POSIX,甚至Linux都不能保证这种行为,因为它必然会限制一种极不常见情况下的实现。由于各种原因对数据包进行重新排序是很常见的,并且允许Linux出于性能或其他原因(例如数据包过滤或QoS)对数据包进行重新排序可以提高吞吐量

即使发送方确实保证了这种行为,接收方仍可能遇到缓冲区过满或临时网络硬件问题,这将阻止数据包被正确接收,因此发送端的任何保证仍然毫无意义。不管怎样,如果上面没有更高级别的协议,就不能依赖UDP数据包的顺序传递


如果您需要顺序检索和重试,但无法使用TCP,请查看QUIC以了解如何执行此操作的示例。您可能(也可能不)想要实现加密部分,但协议分层可能会有所帮助。

它们不保证按顺序到达,或者根本不保证按顺序到达,这是很重要的。因此,在发送者身上发生的事情是无关紧要的。如果不相关,我就不会问它了!:)对于更多上下文,这是一个现有协议,用于与无法容纳整个TCP堆栈的嵌入式设备通信。linux机箱和嵌入式设备通过直连电缆连接,因此网络中无法进行重新订购。如果相关,您尚未说明如何进行。即使寄件人有铁一般的保证,对接收人也没有任何帮助。网络中的任何元素,包括发送方和接收方,都可以自由地重新排序UDP数据报。我认为,当在本地计算机上使用Unix域套接字时,这个问题可能会成为一个有趣的思想实验,因为数据报可能不会进入网络堆栈。如果是这种情况,那么你应该在问题中添加额外的信息。否则,您将获得标准担保。但也请参阅并感谢您的参考资料。我澄清了问题中的设置。它确实正在进入网络堆栈,但数据包只通过一条链路。您提供的链接信息量不大(但感谢您提供)。在其中一个链接中使用了windows网络堆栈,我对此一无所知,而在另一个链接中,竞争条件似乎是罪魁祸首。据我所知,由于数据包过滤和QoS,数据包的重新排序发生在网络队列中,正如我提到的,我使用默认的pfifo_fast,它只根据ToS位进行最小的过滤,并且我发送的所有数据包都设置了相同的ToS位。我知道我还需要处理其他网络问题,如丢包和延迟,但我试图了解重新订购是否不是这些问题之一。此外,我正在处理一个现有的系统,因此重新设计它超出了范围。此外,这里的许多答案都假设UDP数据包将穿越互联网。事实并非如此。它只能通过专用的以太网电缆传输。我的答案是正确的。不能保证它会工作,Linux可以用你的数据包做任何它想做的事情。即使它现在起作用,将来也可能不起作用。我知道这可能不方便,但事实就是这样。谢谢你的回答。我相信这个职位是以互联网为中心的,假设所有的网络逻辑都是由互联网驱动的。我认为那是不对的。Linux为各种嵌入式设备和其他可能需要小心与网络驱动程序交互的应用程序提供了动力。这种情况已经存在,一旦数据包到达以我提到的方式配置的网络队列,就会强制进行排序。因此,很难想象内核在数据包到达网络队列后,会尽一切努力对其进行排序,但在数据包到达网络队列之前会对其进行重新排序。