Wireshark抓包
TCP三次握手
+1=1。回复SYN,ACK报文。
握手3:58884端口收到SYN,ACK后,通过收到握手2的报文,ACK=1,知道8043端口同意建链,自己也开心的回复一个ACK=0(握手2报文的SEQ)+1=1。作为同意建链的答复。
至此三次握手完成了。
HTTP请求
HTTP请求如下。第20个报文。
HTTP相应如下,第187个报文:
从22-187都是文件传输接口的相应。那么为什么会有这么多报文?这就要说TCP分段。
TCP分段
一个大文件如何通过网络传输?
能通过一个报文讲大文件传过去么? 不行的。
TCP层有MSS。也就是如果用TCP协议发送大文件,超过TCP单报文的最大值,就会再TCP层被分段发送。
备注:IP的MTU,这个主要是针对UDP等协议的。也就是用UDP发送大内容,如文件流,那么会被IP层分片发送。
再回过头去看这个获取下载内容的HTTP报文。一个Request的HTTP请求。
和一个Reponse的HTTP请求之间有很多交互的报文,这些报文都是要传输的内容经过TCP分段后,传输交互的内容。
分段大小
TCP分段大小,是IP层分片MTU-40得到的值就是TCP分段的MSS值。40=20(IP头)+20(TCP)头。
MSS的值与客户端和服务器都有关系,最终使用协商最小值作为传输的MSS值。
MSS值再TCP建立连接的3次握手阶段完成。分别是SYN,SYN ACK这两个阶段,如下图所示。双方的MSS都是65495。那么通信过程中协商的MSS值就是65495。
TCP 窗口
看到抓包中有很多特殊的报文,如上。包括TCP WINDOW FULL和TCP ZeroWindow以及TCP Window update标记的报文。看下这些是怎么产生的以及是怎么工作的。
TCP接收和发送有滑动窗口机制。重要的标识包括Win字段,就是说名窗口大小。
如上图所示。60号报文代表,报文接收方给服务器说自己的win=65535。并且通过ACK可以看到,接收方要接收到报文下次要从98305byte的位置开始。
这个时候服务器就继续发送61号报文,PSH,ACK类型,Req=98305。Len=32768。
接着发送62号报文,PSH,ACK类型,Req=131073,Len=32768。
可以看出来当前已经发出的报文长度是65536。已经等于最后一次收到ACK,也就是60号报文中最大的Win长度了。服务器就知道自己发送的报文已经到接收方的接收临界了。就不在发送了。所以报文类型是TCP Window Full。代表接收方的TCP Window已经满了。接下来要等接收方,发确认的ACK了。
接收方发送的65号报文,ACK=163841,也就是62号报文的REQ+Len,代表已经收到61,62报文的数据了。并且自己此时的Window长度是0。通知服务器自己的Win是0了。没有能力收报文了。
当然接收方收到报文后,通过滑动窗口处理报文,内核将内容读取到接收缓冲区,并供上层应用使用。
处理了一会(当然时间很短),接收方有足够的Window长度了,就发送了72号报文。标记TCP Window Update。代表自己的Window长度更新了,告诉服务器可以继续发送了。
服务器收到这个后,就继续发送了。。。。。。
HTTP响应
经过一堆数据报文的传输,最终服务器发送完了所有文件数据。
并且计算出来Data数据长度1048676byte。以及服务器相应的HTTP的Header信息。
客户端拿到这些数据,根据HTTP协议,做对应处理。
比如浏览器拿到这个HTTP Response报文后,看到Content-disposition里面写的是attachment,filename=abc。
那就会弹出问询窗口,询问用户是打开,还是保存附件。