TCP粘包问题又叫做数据的无边界性,在上一节中我们介绍了在创建套接字的时候,是会同时创建socket输入、输出缓冲区的。也就是说,write函数只要将要写的数据全部写入了输出缓冲区,函数就会返回,至于将数据发出去就是TCP协议的事了,而如果客户端在读取的时候,也是从输入缓冲区中读,并且是尽可能多的读取,那么如果服务器分几次发给客户端的数据,客户端可能就一次性全给读过来了,比如服务器分三次分别发了1,2,3三个数据,但是客户端一次性从缓冲区读,就读到了123。这显然是不正确的。

一些通用的做法:
1.发送固定长度的数据,不够的用0填充,这样和客户端约定好,每次我的包长度就是固定那么长,那么客户端解析数据就有了保证。但是这样做第一效率不高,第二长度不好控制,万一需要发送较长的包则会出现问题。

2.发送数据的头部加一个长度信息。客户端拿到数据的时候就能知道这个包的长度是多少。

3.在数据包的尾部加上一个特殊字符,标记包的结束。

笔者在实习期间对基于TCP的网络文件系统协议NFS进行了解析,一般协议中是有部分长度信息的。即使发生了分片(即单个包的长度大于分片的最大长度),只需要根据长度信息,就可以等待包到来,直到长度满足,就能将整个包重组起来了。