Waking-Up icon indicating copy to clipboard operation
Waking-Up copied to clipboard

增加“TCP粘包”的相关知识

Open Ankh-L opened this issue 2 years ago • 0 comments

"什么是TCP粘包"在面试中似乎还挺常见,仓库删掉了这个问题的说明,还是有必要了解一下的。首先“TCP粘包”不是TCP的问题,而是应用开发者的问题。

现象:一次recv就得到了多次send的数据,就好像多次发送的数据粘在了一起。 原因:因为TCP是面向字节流的,只负责把数据以有序的字节流的形式发出,把几次发过来的数据区分开是应用层需要做的事情。 处理办法: 1.固定包长的数据包。 顾名思义,即每个协议包的长度都是固定的。举个例子,例如我们可以规定每个协议包的大小是 64 个字节,每次收满 64 个字节,就取出来解析(如果不够,就先存起来)。这种通信协议的格式简单但灵活性差。如果包内容不足指定的字节数,剩余的空间需要填充特殊的信息,如 \0(如果不填充特殊内容,如何区分包里面的正常内容与填充信息呢?);如果包内容超过指定字节数,又得分包分片,需要增加额外处理逻辑——在发送端进行分包分片,在接收端重新组装包片(分包和分片内容在接下来会详细介绍)。 2. 以指定字符(串)为包的结束标志。 这种协议包比较常见,即字节流中遇到特殊的符号值时就认为到一个包的末尾了。例如,我们熟悉的 FTP协议,发邮件的 SMTP 协议,一个命令或者一段数据后面加上"\r\n"(即所谓的 CRLF)表示一个包的结束。对端收到后,每遇到一个”\r\n“就把之前的数据当做一个数据包。这种协议一般用于一些包含各种命令控制的应用中,其不足之处就是如果协议数据包内容部分需要使用包结束标志字符,就需要对这些字符做转码或者转义操作,以免被接收方错误地当成包结束标志而误解析。 3. 包头 + 包体格式。 这种格式的包一般分为两部分,即包头和包体,包头是固定大小的,且包头中必须含有一个字段来说明接下来的包体有多大。

参考资料:https://www.zhihu.com/question/20210025

Ankh-L avatar May 16 '22 13:05 Ankh-L