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

Kei*_*ino 18 tcp packet

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

是否更常见的是告诉服务器它将在数据之前接收的数据包的全长或是否有标记数据包末尾的内容?

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

Tho*_*nin 32

TCP提供连续的数据流.TCP是使用数据包实现的,但TCP的重点是隐藏它们.

把它想象成你想要画的墙.墙由砖砌成.用砂浆将砖粘在一起,并施加石膏使墙壁表面变得光滑.砖是IP包,TCP是石膏.

所以现在你有了光滑的TCP隧道,你想在其中添加一些结构.您想要绘制框,以便您的图形彼此分开.这就是你想要做的:在你的数据中添加一些"管理"结构(图纸周围的方框).

许多协议使用a的概念packet,它是一组以固定格式管理头开头的数据.标头包含足够的信息来决定数据包的结束位置; 例如,它包括分组长度.HTTP这样做,与Content-Length报头,或(与HTTP/1.1)与"块传输编码",其中数据被划分成一个或几个小分组,每个具有由恰好一个小分组长度指示的一个简单包头.

另一种方法是使用一个特殊的终止序列,它不能出现在"普通数据"中.如果您的数据是文本,那么您可以使用值为零的字节作为终止符.

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


Sev*_*yev 5

从 HTTP 中获取线索。

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

与 HTTP 一样:标头以 CR-LF-CR-LF 结尾。如果有超过标头的数据,则数据长度位于标头之一中。


小智 5

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

如果您的流量已加密,这将超越 HMAC。