TCP协议为操作系统底层协议,能够保证应用层获取到完整的、顺序一直的包序列。但TCP不提供具体的分包,需要上层协议自己解决。TCP发送给上层协议的数据是一个没有意义的字符串序列。如何解释这段序列,需要应用层定义,也就是应用层协议规范的内容。
应用层协议按格式一般可以分为文本协议和二进制协议。文本协议最常见的就是HTTP,二进制协议如websocket。无论是哪种协议,都需要对格式严格定义,以方便程序对字符串序列进行分包、拆包。
HTTP协议通过两种方式定义协议帧(一个HTTP请求或一个HTTP响应)结束标志。第一种是在http header中使用Content-Length头给出body长度,header与body使用\r\n\r\n分隔,这样我们就能够确定一个HTTP帧的开始与结束。另外一种是chunked编码的http帧,通过在header中使用Transfer-Encoding:chunked标志**该编码方式,消息体由数量未定的块组成,并以最后一个大小为0的块为结束。每一个非空的块都以该块包含数据的字节数(字节数以十六进制表示)开始,跟随一个CRLF (回车及换行),然后是数据本身,最后块CRLF结束。在一些实现中,块大小和CRLF之间填充有白空格(0x20)。最后一块是单行,由块大小(0),一些可选的填充白空格,以及CRLF。最后一块不再包含任何数据,但是可以发送可选的尾部,包括消息头字段。消息最后以CRLF结尾。
分包采用的俩种方式:1)服务器响应的报文长度经常是可预测的,即输出的内容长度能确定,使用content-length;2)服务器响应的内容长度不能确定,使用Transfer-Encoding编译格式,即分块。 Content-length:长度 Transfer-Encoding: chunked
|