c++ - TCP 数据包通常重新排序吗?

标签 c++ tcp boost-asio packet-sniffers packets

我正在重新实现一个旧的网络层库,但这次使用的是 boost asio。我们的软件是与第 3 方软件进行 tcpip 对话。几条消息在双方都表现得很好,但有一种情况我误解了:

第 3 方一个接一个地发送两条消息(消息 A 和 B)(真正的短时间)但我在 tcp-packet 1 中只收到消息 A 的一部分,消息 A 的结尾和整个消息 B在 tcp-packet 2 中。(我用 wireshark 嗅探)。

我没有想到这种情况,我想知道它是否与 tcp 常见,我的层是否应该适应这种情况 - 或者我应该告诉第 3 方检查他们在他们这边做了什么,以便我在不同的数据包中收到了两条消息。

最佳答案

数据包可能会被分段并乱序到达。在将数据作为传入流呈现给应用层之前,接收它们的 TCP 堆栈应该对它们进行缓冲和重新排序。

My problem is with message B, that I don't see because it's after the end of message one in the same packet.

您不能依赖“消息”与“数据包”的一对一映射:对于应用程序,TCP(而非 UDP)看起来像是“流”协议(protocol)。

通过 TCP 发送的应用程序需要另一种方法来分隔消息。有时这是通过标记每条消息的结尾来完成的。例如SMTP消息结束标记如下:

The transmission of the body of the mail message is initiated with a DATA command after which it is transmitted verbatim line by line and is terminated with an end-of-data sequence. This sequence consists of a new-line (), a single full stop (period), followed by another new-line. Since a message body can contain a line with just a period as part of the text, the client sends two periods every time a line starts with a period; correspondingly, the server replaces every sequence of two periods at the beginning of a line with a single one. Such escaping method is called dot-stuffing.

或者,协议(protocol)可以在每条消息的开头指定一个前缀,以字节为单位指示消息长度。

如果您正在对 TCP 堆栈进行编码,那么您将可以访问 TCP message header :“数据偏移量”字段告诉您每条消息的长度。

关于c++ - TCP 数据包通常重新排序吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13457100/

相关文章:

unix - Codeigniter DB 设置 - 为什么 127.0.0.1 有效,而 localhost 无效

c++ - 当 boost deadline_timer 在超时处理程序中被销毁时会发生什么

android - 将 (Boost) Asio 与 Android NDK 结合使用的限制

c++ - 从 std::map 访问时,Eclipse CDT 无法解析结构函数

C++ 方法调用和类型范围解析歧义

c++ - 静态成员声明为 const 但初始化为 constexpr

c++ - 如何编写通用函数来处理不同类型的流?

c# - 输出图像字符串C++到C#父程序(不保存到硬盘)

tcp - 除了编写 TCP/IP 数据中继之外,还有什么替代方案?

linux - 如何永久更改 MTU 设置