粘包 拆包(分包) 半包

粘包、拆包、半包理解

TCP是一种面向流的网络层传输协议,在使用TCP做为传输层协议时,可保证数据的顺序性和可靠性。网络

应用层在使用TCP协议传输数据时,可采起两种方式:blog

  • 短连接:客户端同服务端完成一次通讯(客户端只发送一次请求,并接收到响应),关闭TCP链接;
  • 长链接:客户端持续同服务端进行通讯(客户端不停的发送请求,并接收到响应),不关闭TCP链接;

使用短链接时,可经过TCP链接是否关闭判断是否完成了一次请求响应通讯。但每次请求必须重建TCP链接,会致使请求响应一会会存在一个TCP握手延时。所以常常使用长链接进行较高频率的请求响应通讯。coding

但在使用长链接时,因为客户端可能会发送多个请求,服务端会同时持续收到数据。服务端接收到的数据中可能包含多个请求数据,此时请求数据是粘连在一块儿的(粘包),须要进行拆分(拆包)。请求

还有一种状况,服务端接收到的数据中包含一个不完整的请求数据,剩余数据还未接收到(半包),服务端须要继续接收数据直到接收完整请求数据。方法

  • 粘包:只会在长链接通讯方式中存在,不一样的请求数据会被服务端同时接收到,而服务端暂时没法将其请求数据区分为请求1或者请求2。
  • 拆包:将粘连在一块儿的不一样请求数据进行拆分
  • 半包:服务端接收到的请求数据不完整,剩余数据正在传输过程当中。

粘包、拆包、半包图示

粘包:服务端接收到的请求数据牢牢挨着,暂时没法分离。im

 

拆包:服务端将接收到的数据拆分为不一样的请求数据通信

 

半包:拆包过程当中发现某个请求数据不完整,须要继续接收数据。数据

如何拆包、判断半包

如何判断不一样请求数据的起始和结束位置,是拆包和判断半包的关键。客户端

经常使用的方法有两种:协议

  • 包头(包含包体长度)+包体
  • 包头(包含预约义的界定标识)+包体+包尾(包含预约义的界定标识)

第一种方法,读取固定长度的包头后,可根据包头中指定的包体长度读取包体,直到读取到完整的包体。

  • 问题:若是包头中的包体长度同实际的包体长度不附,会致使后续的全部数据拆包都出现问题,且没法恢复。

第二种方法,在持续读取数据时,须要判断读取的数据中是否出现了界定标识,出现了便可判断是否已到旧包的包尾或者新包的包头。包头和包尾至少存在一个。

  • 问题:读取过程当中需一直判断界定标识,在高速传输数据时,会致使微小的处理延时。

 

http协议能够说是以上两种方法的结合,http header信息经过第二种方法获取,两个CRLF后标识http header结束,http response body经过第一种方法获取(content-length),也会采用第一二种结合方式获取(transfer-Encoding: chunked)。

相关文章
相关标签/搜索