我正在重新实现一个旧的网络层库,但这次使用的是boost asio。我们的软件是使用第三方软件进行tcpip对话。几条消息在双方都表现得很好,但有一种情况我误解了:
第三方一个接一个地发送两条消息(消息A和B)(实际短时间)但是我只收到tcp-packet 1中消息A的一部分,以及消息A的结尾和整个消息B在tcp-packet 2.(我用wireshark嗅探)。
我没有想到这种情况,我想知道它是否与tcp相同,如果我的图层应该适应那种情况 - 或者我应该对第三方说要检查他们在他们身边做什么,以便我收到了不同包中的两条消息。
答案 0 :(得分:4)
是的,这很常见。 TCP / IP是一种流协议,您的“逻辑”数据包可能会分散在许多“物理”数据包中,因此客户端负责组装更高级别的数据包。此外,TCP / IP保证正确的排序,因此您不必担心组装无序数据包。
答案 1 :(得分:4)
数据包可能会碎片化并且无序到达。接收它们的TCP堆栈应该缓冲并重新排序它们,然后将数据作为传入流呈现给应用程序层。
我的问题是消息B,我没有看到,因为它是在同一个数据包中的消息1结束之后。
你不能依赖与“数据包”一对一映射的“消息”:对于应用程序,TCP(不是UDP)看起来像“流”协议。
通过TCP发送的应用程序需要另一种方法来分隔消息。有时这是通过标记每条消息的结尾来完成的。例如,SMTP标记消息结束如下:
使用a启动邮件正文的传输 DATA命令,然后逐行逐字传输 终止于数据结束序列。这个序列包括 一个新行(),一个句号(句号),然后是 另一条新线。由于邮件正文可以包含只有一行的行 作为文本的一部分,客户端每次发送两个句点 线以一段时间开始;相应地,服务器替换每一个 一行开头的两个句点的序列。 这种转义方法称为点填充。
或者,协议可以在每条消息的开头指定一个前缀,这将指示消息长度(以字节为单位)。
如果您正在编写TCP堆栈,那么您将可以访问TCP message header:“数据偏移”字段会告诉您每条消息的持续时间。
答案 2 :(得分:3)
你的问题根本与TCP无关。您的问题是您希望asio为您解析消息。它没有,你必须实现它。