前言 当我们在浏览器输入http://qf.56.com/activity/galaxy2018/topic.do,并且按了回车键;一个http请求,到底是怎么样走完它的一生的呢?我们可以用wireshark来抓包还原整个过程。
抓包 说到抓包,我们可能更熟悉fiddler或者Chrome等抓包工具,比如这样子:
![](https://img.haomeiwen.com/i1605579/7945ded51ccb56df.png)
其实这是一个完整http请求的包,即从把请求从本地发到服务器,服务器把数据返回回来,所有的过程都浓缩在这里一个包里面。但是实际上,一个完整的http请求,应该包括DNS获取IP、建立TCP连接、发送请求、获取响应、释放TCP连接等...这些只有在wireshark才能完整的看到,现在我们用wireshark,从更底层的角度,看看什么叫做数据包。
wireshark-HTTP包简介
![](https://img.haomeiwen.com/i1605579/5734092a02021fa9.png)
这就是一个wireshark抓下来的普通的http请求包,请求地址为/activity/galaxy2018/topic.do,一共分为6层。Frame为最外层物理层;Ethernet II为数据链路层,Src为本机的mac地址,Dst不是服务器的mac地址,而是我们公司某个路由或者交换机(同个网络)的mac地址;Internet Protocol Version 4为网络层,Src为本机IP,Dst为服务器IP;Transmission Control Protocol为TCP传输层,本机socket端口为27478,服务器端口为80;最后一层为HTTP应用层;第五层我们看看下图,在七层协议中,传输层和应用层之间应用是表示层和会话层,但是这一层的数据看起来不像;但看起来更像另外一种东西。在这里我大胆猜测,这应该是因为该TCP包过大,在网络层被拆成两个包,而看到上图的最前面的16和上一个包15也为TCP包,似乎也印证了我的想法。
![](https://img.haomeiwen.com/i1605579/17e39ce90b3dd991.png)
完整过程
![](https://img.haomeiwen.com/i1605579/bd09038d77fcbc78.png)
![](https://img.haomeiwen.com/i1605579/799416d633270b65.png)
一个完整的请求过程实际上包括了上面的DNS和下面的TCP过程,如果浏览器缓存了DNS的话,实际上有时候是捕捉不到上面的DNS包的。
DNS
![](https://img.haomeiwen.com/i1605579/bd09038d77fcbc78.png)
DNS有两个包,第一个包是DNS请求包,我的电脑发了一个请求包给DNS服务器(10.7.74.11),想让它帮忙找找qf.56.com的IP;第二个包是DNS响应包,显然DNS已经找到了qf.56.com对应的IP,所以把它返回回来,他返回的结果也很有趣,我们可以看到第四层是User Datagram Protocol(UDP),此外,在Answers中,qf.56.com经过了两轮查询,第一轮查询查到了cname 为qf.56.com.cdn20.com,第二轮才根据cname查找到addr为113.107.57.22。那么cname是什么呢,我们可以理解成别称;假如现在我们有qf.56.com -> 113.107.57.22;mail.56.com -> 113.107.57.22;file.56.com -> 113.107.57.22;某一天我们换服务器,换ip了,如果没有cname的话,我们需要同时该qf.56.com,mail.56.com;file.56.com,但是如果我们先设置了这些域名对应的cname为qf.56.com.cdn20.com,那么我们只需要改qf.56.com.cdn20.com对应的ip即可。
![](https://img.haomeiwen.com/i1605579/cfa7d186341a11a0.png)
三次握手(建立TCP连接)
三次握手上一篇博文(运输层学习)已经分析过了,不过这里有个地方有点意思,上一节我们知道过TCP首部有个options(选项)字段,但是我看了那么多TCP的包,好像只有三次握手的前个包才有这个字段。
![](https://img.haomeiwen.com/i1605579/de333baa843ba683.png)
真正的请求头
![](https://img.haomeiwen.com/i1605579/7fae8d7d9baadbb1.png)
我们可以看到这里的请求头被拆包了;当TCP包超过MSS的时候,在IP层会被拆包;上面建立连接的时候两个MSS一个为1460,一个为1380,TCP会取小的MSS,所以就是取1380;从下面的图可以看到TCP数据部分长度确实是1380。Frame15和Frame16组成一个完整的请求头。
![](https://img.haomeiwen.com/i1605579/ba8e9724480be010.png)
对真正的请求头的确认
我们知道TCP是可靠协议,即接收方会对发送方的每一个请求都进行确认。上面的真正的请求头有两个包,所以这里就有两次响应(不一定两次请求就有两次响应)。
![](https://img.haomeiwen.com/i1605579/5d44bb59dfb6d76b.png)
真正的响应体
真正的响应体实在太长了,所以被拆成了四个包,这里略感奇怪的是为什么会被拆成大小不相等的4个呢?
![](https://img.haomeiwen.com/i1605579/dab12901b5a02651.png)
![](https://img.haomeiwen.com/i1605579/7fa8bf319c9eed4f.png)
对真正响应体的确认
这里我要郑重解释下为什么之前两个请求有两个确认,这里四个响应却只有一个确认。这是因为根据连续窗口ARQ协议,接收方接收到某个数据包,如果新进来的字节能和前面的已经接收确认的字节连在一起,就会发送确认包;如果不能,如果不能,会等待新的数据包进来,直到能和前面的字节流连在一起。很显然,两个请求包中,应该是Frame15先到,它发现可以连在一起了,所以发送确认,然后Frame16也来了,他发现又可以连在一起了,于是又发送了确认。而四个响应包中,我估计是Frame22最后才到,所以才发一个确认包。
![](https://img.haomeiwen.com/i1605579/8238395c79518c88.png)
四次挥手(释放连接)
这次又看到不一样的东西,为什么是服务端主动提出的释放连接,难道教科书上面都是在骗我的。不过四次挥手的内容确实如上一节所说。
![](https://img.haomeiwen.com/i1605579/6e8dffc481711a60.png)
网友评论