如何标记TCP数据包的结尾?

如何标记TCP数据包的结尾?,tcp,packet,Tcp,Packet,在客户机/服务器应用程序中,如果不同长度的文本数据将在客户机和服务器之间来回发送,我应该如何标记正在发送的数据包的结尾?例如,当服务器从客户机接收数据包时,服务器如何知道客户机数据包已完全接收 更常见的做法是在数据发送之前告诉服务器它将要接收的数据包的完整长度,还是在数据包的末尾有标记 发送的某些数据长度只有几个字符,而某些数据可能有数千个字符。将数据包的结构设置为在开头包含一个长度字段。从HTTP获取提示 使用字符的终止符序列,或者在消息头的某个位置指定长度,或者使用两者的巧妙组合 与HTTP

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

更常见的做法是在数据发送之前告诉服务器它将要接收的数据包的完整长度,还是在数据包的末尾有标记


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

将数据包的结构设置为在开头包含一个长度字段。

从HTTP获取提示

使用字符的终止符序列,或者在消息头的某个位置指定长度,或者使用两者的巧妙组合


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

TCP提供连续的数据流。TCP是使用数据包实现的,但TCP的全部目的是隐藏数据包

把它想象成一堵你想画的墙。这墙是砖砌的。砖用灰浆粘在一起,并涂上灰泥,使墙面光滑。砖头是IP包,TCP是石膏

现在你有了平滑的TCP通道,你想在其中添加一些结构。您希望绘制长方体,以便图形彼此分开。这就是您想要做的:向数据中添加一点“管理”结构(图形周围的框)

许多协议使用
数据包的概念,这是一组以固定格式管理头开始的数据。报头包含足够的信息来决定数据包的结束位置;e、 例如,它包括数据包长度。HTTP使用
内容长度
报头,或(使用HTTP/1.1)使用“分块传输编码”,将数据拆分为一个或多个小数据包,每个小数据包都有一个简单的报头,其中正好包含一个小数据包长度指示

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


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

如果发送方知道长度,则发送方应将长度作为固定大小字段提前提供,后跟可变大小数据

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


以后,你可能会在你的“标题”中找到其他的位置。你会很高兴你有了一些结构来发展你自己的第五层协议。

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

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


如果您的通信量被加密,这就超过了HMAC。

我猜您担心的不是TCP数据包,而是TCP流中的应用程序级消息,对吗?当您需要发送任意数据时,终止符序列会变得很棘手,因为数据可能(碰巧)包含终止符序列,这会混淆接收解析器。您可以通过实现某种转义码协议来避免这种情况,但在这一点上,事情比只发送长度字段更复杂,因此您最好只发送长度字段,并保持简单。