写在前面:
什么是http,可以做什么?
HTTP(HyperText Transfer Protocol) 翻译过来就是超文本传输协议 ,不严谨讲就是服务器如何把网页传输给客户端浏览器。所以日常使用的浏览器查看网页多数都是使用的http协议。
本篇直接从数据包下手,看看一次http请求到底经过了那些步骤~~
讲网络不得不谈的OSI七层模型:
七层模型,亦称OSI(Open System Interconnection),参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,一般称为OSI参考模型或七层模型。(来源于百度百科)
个人理解:网络数据传输都是依靠数据包来传送,类似于快递包裹在物流体系中传送。那包裹如何一层层打包,消费者如何一层层拆快递,ISO定义了一个标准体系,就是OSI,有了OSI标准不同设备之间互相传递数据有了秩序。后来TCP/IP协议借鉴OSI七层,发展了更为简单的OSI四层协议,各个协议分层如下:

闲言少叙,直接上ensp实验做起来:

简要说明:各服务器网关均为出接口对应的路由器的接口的ip地址。
抓包过程:
打开wireshark抓取lsw1交换机的E0/0/4接口数据包,然后client请求server.test.com的http服务。
抓包结果:

过程分析:
数据包如何一步步到达服务器,服务器又如何返回数据给客户端(均以四层模型为参考)
1)数据封装过程:
数据封装由上层至下层一层层封装,即数据由应用层产生--->传输层--->网络层(ip层)--->网络接口层,一层层封装相应头部字段
2)数据解封装过程:
数据接封装由下层至上层一层层解封装,即从最外面的网络接口层到网络层再到传输层最后到应用层一层层解封装,就像剥洋葱,一层一层的剥开~~
按照以上规则开始分析具体过程:
数据封装:
1)物理层:

物理层可以看到此数据包的长度,封装类型,时间信息还有封装的协议等一些非常基础的信息。不负责任的讲物理层信息通常不太关注,不再细说。
2)数据链路层:
由于物理层显示封装类型为Ethernet以太网封装,以太网帧格式如下:


比较重要的几点,数据链路层有源mac地址,目的mac地址,封装协议等。
数据链路层抓分分析如下:

问题来了:源mac地址自己本身,封装协议也知道,但是目的mac地址是不清楚的,所以第一步要先获取目的地的mac地址。
注意,此时获取到的是客户端网关的mac地址,而不是服务器的mac地址,为啥?客户端距离服务器十万八千里即使知道了服务器的mac地址,数据包在经过第一个路由器的时候被发现目的mac地址并不是自己就要丢弃此数据包,所以此时的mac地址是客户端的网关mac地址,路由器在收到之后将源mac改为自己出接口的mac,目的mac改为路由表中下一跳的mac,就这样mac地址在很多个路由器之间这样改来改去一步一步到达服务器端~~~(关于路由器的东西太多了,有点扯远了)
重点来了:知道ip地址如何确定mac地址???
答案是:ARP协议,(通俗讲就是通过ip地址获取mac地址的协议)所以在抓包的时候最开始会有两个arp的包,过程简单来说客户端(10.0.10.10)发送一个广播包在自己的局域网内喊一嗓子,谁是10.0.10.1(客户端的网关)?告诉10.0.10.10一下。
然后路由器收到广播包之后单播回复客户端,我是10.0.10.1,我的mac地址是00:e0:fc:3a:37:fd,至此客户端获取到了目的mac地址(arp有缓存所以短时间内不会重复发arp请求)
arp抓包情况如下:arp请求是广播包请求,目的mac未知所以全为0,回复包为单播包,源目ip,源目mac均有。


3)网络层
对于http协议,网络层封装ip报文头,主要信息为版本号:ipv4还是ipv6,源ip,目的ip,下一层封装的协议类型(tcp,udp等)

网络层抓包如下:ipv4协议报文

问题来了:目前只知道访问server.test.com这个域名,但是并不知道这个域名的ip地址是多少
域名解析服务(DNS)来了
此时客户端会先检查自己的本机hosts文件,若没有客户端会请求自己配置的的dns服务器,服务器会查看本地的dns表项,如果没有则向根域请求一层层的查询知道返回结果有还是没有。
所以此时客户端会发送dns请求到dns服务器,然后dns服务器会返回数据包告知此域名对应的ip地址。此时有两个dns数据包。
至此目的ip地址获取到了。
DNS抓包如下:


4)传输层
传输层主要是tcp还是udp协议,主要是传输稳定性相关,tcp需要三次握手建立连接,相较于udp传输更加稳定可靠,http采用tcp三次握手连接。
tcp报文主要有源端口目的端口,seq number,ack number等信息。

传输层tcp协议抓包如下:

传输层udp抓包如下:udp报文非常简单,只有源端口目的端口,长度,校验,时间间隔等。

注意:DNS服务既可以使用tcp连接,也可以使用udp连接
问题:为啥要端口号?
如果说用ip地址来区分一台主机,那端口号就是用来区分不同的服务,比如http服务默认80端口,dns端口53,ip:port组成了特定主机的特定服务。
根据端口号分配原则:端口号2个字节16比特,端口号范围0~65535
其中0~1023为特定端口,已经分配给特定服务。
所以源端口为客户端的大于1023的随机端口,目的端口为默认http服务80端口(如未指定端口)
tcp需要三次握手才可以建立连接,所以会有三个tcp的数据包。
5)应用层
http协议报文,http协议报文主要分为请求报文和响应报文;
请求报文由三部分组成:
请求行(请求方式,URL,http协议版本)
报文头(包含请求的信息等)
报文体
类似如下图:

响应报文同样三部分组成:
响应行:报文协议版本,http状态码
响应头:各种首部字段
响应主体;

相关解释:
请求方式:以那种方式请求http服务,有get,post,put等好多种,默认get
请求URL:浏览器输入的网址
http协议版本:比较早的有http0.9版本,后来http1.0和1.1版本,现在基本都是1.1版本
http状态码:不同的状态码对应的http服务的状态,2xx基本为成功,3xx基本是重定向代理之类,4xx一般的请求错误,比如著名的404,找不到对应的资源,5xx一般为服务错误,比如http服务器出现异常。
http协议抓包如下:http请求报文

http回复报文:

总结:从数据包来看,客户端的请求数据要经过以下几个过程,首先ARP请求(获取目的mac)--->DNS解析(获取目的ip)--->tcp三次握手(建立连接)--->http请求报文--->服务器回复http报文
报文封装过程:应用层封装(比如请求http请求)--->传输层封装(源端口目的端口等)--->网络层封装(源ip目的ip等,需要用到dns解析)--->数据链路层封装(源mac目的mac,需要用到ARP协议)--->物理层封装(帧格式等)




