网络协议:协议部分和数据部分
参考:
https://blog.csdn.net/qq_42882717/article/details/114265364(如何确定TCP数据包长度)
https://blog.csdn.net/ydyang1126/article/details/56845358(HTTP协议中body长度的确定)
上图
经验总结
1,每一层封装和获取每一层自己的协议数据
2,传输层协议已经是操作系统来完成了,开发只能基于tcp/udp来定义自己的应用数据
tcp数据包长度
在tcp数据包处理的实战中,总会确定payload的长度
但是呢,tcp头部中没有确定的tcp_len长度,非常的烦
所以一般如下确定payload长度:
从IP报头(IP .len)中提取“总长度”,然后减去“IP报头长度”(IP .hdr_len)和“TCP头长度”(TCP.hdr_len)。
在内核中也就是 ip->tot_len - ip->len -hdr_len(tcp)。
HTTP协议中body长度的确定
背景:
http请求是基于TCP协议之上的,那么,当客户端在发起请求前,需要先与服务端建立TCP连接,而每一次的TCP连接是需要三次握手来确定的,如果客户端与服务端之间网络差一点,这三次交互消费的时间会比较多,而且三次交互也会带来网络流量。当然,当连接断开后,也会有四次的交互,当然对用户体验来说就不友好了。
定义:
而http请求是请求应答式的,如果我们能知道每个请求头与响应体的长度,那么我们是可以在一个连接上面执行多个请求的,这就是所谓的长连接。
前提:
先确定请求头与响应体的长度。
对于请求头:
a、如果当前请求需要有body,如POST请求,那么nginx就需要客户端在请求头中指定content-length来表明body的长度。
b、如果请求头不需要body,遇到两个连续回车时,即可确定请求头结束。
对于应答体:
a、对于http1.0协议来说,如果响应头中有content-length头,则以content-length的长度就可以知道body的长度了,客户端在接收body时,就可以依照这个长度来接收数据,接收完后,就表示这个请求完成了。
而如果没有content-length头,则客户端会一直接收数据,直到服务端主动断开连接,才表示body接收完了。 b、而对于http1.1协议来说,如果响应头中的Transfer-encoding为chunked传输,则表示body是流式输出,body会被分成多个块,每块的开始会标识出当前块的长度,此时,body不需要通过长度来指定。
如果是非chunked传输,而且有content-length,则按照content-length来接收数据。否则,如果是非chunked,并且没有content-length,则客户端接收数据,直到服务端主动断开连接。