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

标签 linux sockets network-programming udp posix

我意识到依赖 UDP 协议(protocol)来提供任何排序​​保证都是一个坏主意,应该改用 TCP。请不要回答建议我使用 TCP。

我正在调试一些遗留网络代码,想知道套接字接口(interface)提供的顺序保证是什么。我的设置包括一个运行 Debian 的 linux 盒子,通过直接以太网电缆与嵌入式设备通信。嵌入式设备无法容纳整个 TCP 堆栈,即使可以容纳,遗留堆栈也太旧而无法重构。

具体来说,如果我有一个配置了默认单个 pfifo_fast 的 NIC ,并且我使用单个线程通过单个套接字发送数据包,它们都具有相同的 ToS ,在这些情况下,我能保证我所有的数据包都会按照我发送的顺序通过网络发送吗?

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

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

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

最佳答案

无法保证此行为,因为在一般情况下它是无关紧要的,如 user207421 所述。 POSIX,甚至是 Linux,都不能保证这种行为,因为它必然会限制极其罕见情况的实现。出于各种原因重新排序数据包很常见,允许 Linux 出于性能或其他原因(例如数据包过滤或 QoS)这样做可以提高吞吐量。

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

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

关于linux - 通过单个套接字发送的 UDP 数据包是否保证按顺序发送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57153969/

相关文章:

python - 如何使用相对引用使用子进程运行复杂的python命令?

linux - PulseAudio:获取源(麦克风)的当前音量

通过套接字进行 C# 序列化,一个类正在序列化,另一个类没有

java - 列表数组错误?

php - rename() PHP 函数找不到目录,即使它在那里?

python - 在 Linux 上获取鼠标位置,纯 Python

java - 基于套接字的应用程序的非确定性行为

javascript - 使用事件的feathersjs套接字

javascript - 通过 WebRTC 数据通道实现 WebService 是否可行且合理?

c - 是否可以在 TCP 3 次握手中获取 SYN/ACK 数据包的 TCP 序列号?