【问题标题】:How should I mark the end of a TCP packet?我应该如何标记 TCP 数据包的结束?
【发布时间】:2011-01-24 06:56:03
【问题描述】:

在客户端/服务器应用程序中,不同长度的文本数据将在客户端和服务器之间来回发送,我应该如何标记正在发送的数据包的结尾?例如,当服务器正在接收来自客户端的数据包数据时,服务器如何知道客户端数据包已被完全接收?

更常见的做法是在数据之前告诉服务器它将接收的数据包的全长,还是在数据包结束时标记一些东西?

有些发送的数据只有几个字符长,有些可能是数千个字符。

【问题讨论】:

  • 我猜你担心的不是 TCP 数据包,而是 TCP 流中的应用程序级消息,对吧?

标签: tcp packet


【解决方案1】:

TCP 提供连续的数据流。 TCP 是使用数据包实现的,但 TCP 的全部意义在于隐藏它们。

把它想象成你想在上面画画的墙。墙是砖砌的。砖用砂浆粘在一起,抹灰使墙面光滑。砖是IP包,TCP是石膏。

所以现在您有了平滑的抹灰 TCP 隧道,并且您想在其中添加一些结构。您想绘制方框,以便您的绘图彼此分开。这就是您想要做的:为您的数据添加一些“管理”结构(图纸周围的框)。

许多协议使用packet 的概念,它是一组以固定格式的管理标头开头的数据。标头包含足够的信息来决定数据包的结束位置;例如,它包括数据包长度。 HTTP 使用Content-Length 标头,或者(使用 HTTP/1.1)使用“分块传输编码”来做到这一点,其中数据被分成一个或多个迷你数据包,每个迷你数据包都有一个简单的标头,正好由一个迷你数据包组成-长度指示。

另一种方法是有一个不能出现在“正常数据”中的特殊终止序列。如果您的数据是文本,那么您可以使用值为零的字节作为终止符。

还有一种方法是使用自终止数据。这是一种结构化的数据,您可以随时知道是否已到达元素的末尾。例如,XML 数据被组织为嵌套的标记对,例如<foo>...</foo>。当到达结束标记 (</foo>) 时,您就知道该元素已完成。

【讨论】:

    【解决方案2】:

    以这样一种方式构建您的数据包,使其在开头包含一个长度字段。

    【讨论】:

      【解决方案3】:

      从 HTTP 中获取线索。

      使用终止符序列,或在消息头中的某处指定长度,或巧妙地结合使用两者。

      与 HTTP 一样:标头以 CR-LF-CR-LF 结尾。如果有数据通过标头,则数据长度在其中一个标头中。

      【讨论】:

      • 当您需要发送任意数据时,终止序列会变得很棘手,因为数据可能(巧合)包含终止序列,这会使接收解析器感到困惑。您可以通过实现某种转义码协议来避免这种情况,但此时事情比仅先发送长度字段更复杂,因此您不妨先发送长度字段并保持简单。跨度>
      • OP 说该协议涉及“不同长度的文本数据”。 “文本”意味着可能的字节值的某个子集,例如。 G。没有空字符。有一个终结者。也就是说,OP 更了解协议可能是什么样的。
      【解决方案4】:

      如果在开头对长度进行编码,请注意垃圾。例如,如果您使用 4 个二进制字节作为长度并且某个外部探测器发送了一个 HTTP 请求,那么您最终可能会得到一个巨大的数字并永远等待(更不用说分配一个可能会使您的程序崩溃的缓冲区)。我通过不同的函数发送长度两次并比较它们(例如~len和len xor 0x139AF321)。您还应该设置一个最大值,以防有人主动尝试使您的程序崩溃。如果我得到一个错误的长度,我只是关闭连接。

      如果您的流量已加密,则这超出了 HMAC。

      【讨论】:

        【解决方案5】:

        如果发送者知道长度,那么发送者应该在前面提供长度作为固定大小的字段,然后是可变大小的数据。

        相对于尾部标记的优势在于接收器可以针对预期的数据量进行优化,例如分配正确大小的缓冲区。例如,基于 TCP/IP 协议的存储与您在 TCP/IP 上的问题相同。在这些情况下,标头提供后续预期数据的长度。

        稍后,您可能会在“标题”中找到其他内容。你会很高兴你有一些适当的结构来发展你自己的第 5 层协议。

        【讨论】:

          【解决方案6】:

          如果您觉得特别大胆,可以考虑使用SCTP 套接字而不是 TCP 套接字。

          【讨论】:

            猜你喜欢
            • 2016-12-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多