从浏览器地址输入到网页显示的整个过程
整体流程
从往浏览器输入一个地址到网页的显示,要经过很长的一个流程,中间涉及到计算机网络的许多知识。
首先我们的计算机如果是刚接入网络,并且不是手动设置的方式设置IP地址的话,则需要通过DHCP自动获取一个IP地址。
然后我们再浏览器输入一个域名地址,浏览器就会组装http报文。
组装好http报文后,由于我们输入的是域名地址,需要解析成IP地址,这就需要用到DNS域名解析协议进行域名解析。
然后就要通过TCP协议的三次握手建立连接,建立TCP连接之后,就可以通过这个TCP连接发送数据。
然后不管是TCP三次握手的数据包,还是真正发送数据的数据包,都要通过内网的路由器把它发到外网,这就需要把我们数据包发送到路由器。这时候就需要用到IP地址,通过DHCP我们的计算机已经拥有了自己的IP地址,然后通过DNS域名解析协议也获取到了目标服务器的IP地址,这时候通过目标服务器的IP地址在本机的路由表中查询匹配,就可以把我们的数据包发送到路由器。
路由表中匹配到路由器后,还需要通过ARP协议获取路由器的MAC地址,然后经过交换机转发数据包到路由器。
交换机接收到数据包之后,就会根据下一跳的MAC地址,转发数据包到路由器。
路由器接收到数据包后,会解开外层MAC层的包头,拿到网络层的包头的目标IP地址,在自己的路由表中进行匹配,匹配成功后经过指定的接口把数据包发到外网。
数据包到达了目标服务器所在子网的路由器时,也是经过相同的规则,通过目标IP地址在路由表中进行匹配,然后经过交换机转发到目标服务器,目标服务器接收到数据包之后处理请求,返回响应数据包,也是经过相同的流程到达我们的计算机。
DHCP
一台计算机在刚接入内网时,我们可以给他手动设置一个IP地址,但是如果内网的计算机比较多,都通过手动设置IP地址的方式分配IP地址的话,就会非常的麻烦。于是我么可以通过DHCP方式动态分配IP地址。
使用DHCP动态分配IP,通常需要一个DHCP路由器。我们的计算机刚接入内网时,还不知道DHCP服务器的ip地址,我们的计算机自己本身也没有ip地址,于是就通过广播的方式,广播一个UDP数据包。该UDP数据包的目标ip地址为255.255.255.255,目标端口是67,源IP地址是0.0.0.0,源端口是68。
DHCP接收到UDP数据包,会分配IP一个地址,并通过UDP数据包广播回去。
我们的计算机接收到DHCP服务器返回的UDP数据包之后,如果有多个DHCP服务器给他分配IP,它会从中选择一个,然后广播一个UDP确认数据包。
最后DHCP服务器广播一个返回的ACK报文,这样我们的计算机就获取到了自动分配的IP地址了。
但是有时候DHCP服务器和我们的计算机不在同一个局域网,此时就要通过DHCP中继代理,把DHCP请求代理到DHCP服务器。DHCP中继代理其实就是一个路由器,会以单播的方式把DHCP请求数据包发送到DHCP服务器所在局域网的另一个DHCP中继代理路由器。
http协议报文组装
然后我们在浏览器输入一个域名地址,比如我们输入的就是www.baidu.com,此时浏览就就会组装http协议报文,把它发送到目标服务器,目标服务器再返回一个包含www.baidu.com网页信息的http响应报文。
http请求报文格式:
http响应报文:
DNS
组装好http请求报文以后,由于我们输入的是域名地址,现在要把域名地址解析成IP地址。此时就通过DNS域名解析协议进行域名解析。
浏览器首先查看自己是否有该域名对应的缓存信息,如果有,则直接从缓存中获取该域名的IP地址。
浏览器缓存不命中,则查询hosts文件是否配置了该域名与IP地址的映射关系,如果有,则会返回hosts文件中该域名对应的IP地址。
如果hosts文件中也不命中,则要访问DNS域名服务器查询该域名对应的IP地址。
请求DNS域名服务器时,首先会请求的是本地DNS域名服务器,本地DNS域名服务器也是先从缓存中查询,如果缓存命中,则返回缓存中的IP地址。
如果本地域名服务器缓存不命中,则请求根域名服务器,然后根域名服务器会返回顶级域名服务器(.com)的域名服务器地址。
然后本地域名服务器再请求顶级域名服务器,顶级域名服务器返回baidu.com的权威域名服务器。
本地域名服务器请求baidu.com权威域名服务器,baidu.com权威域名服务器返回www.baidu.com域名对应的服务器IP地址。
然后本地域名服务器会把域名与IP地址的映射关系缓存起来。
TCP协议封装与TCP三次握手
查找到目标服务器的IP地址之后,就要交给传输层进行网络传输了,浏览器请求页面一般是走TCP协议。
TCP协议会把http报文拆分成多个数据包,以流的形式发送。每个数据包会封装一个TCP协议头。TCP协议头包括源端口号、目标端口号、序列号(seq num)、确认序列号(ack num)、以及六个状态位(URG、ACK、PSH、RST、SYN、FIN)等重要信息,其他的信息不太重要就不需要去记忆了。
然后会经历与服务器的三次握手,建立一个TCP连接,才能基于这个TCP连接发送数据。
- 首先是客户端(也就是我们的浏览器)发送一个SYN标志位为1的请求数据包,表示请求建立连接,此时客户端进入SYN-SENT状态;
- 然后服务器接收到之后会返回一个SYN和ACK标志位为1的数据包,表示响应客户端的连接请求,并请求客户端建立连接,此时服务端进入SYN-RCVD状态;
- 最后客户但返回一个ACK标志位为1的数据包,于是双方进入ESTABLISHED状态,表示连接建立成功。
IP协议封装与路由表
然后就是网络层协议栈的处理,使用的是IP协议,会在TCP协议包头的外面套一层IP协议包头,IP协议包头包括源IP地址和目标IP地址。
然后查询路由表,会匹配到掩码为0.0.0.0这一条目,找到路由器网关的地址。
MAC地址与ARP协议
获取到了路由器的IP地址,还要取得它的MAC地址,才能把它发出去。
在外网使用IP地址进行网间路由,而在局域网,则使用MAC地址就可以。并且IP地址是可以更改的,而MAC地址是设备出厂时设置好的并且不可更改,所以比起IP地址来说,MAC地址更能唯一表示一台服务器。
MAC 地址长 6 个字节 48 位,使用十六进制数表示,比如:30-C9-AB-9F-7E-70。
要获取MAC地址,需要使用ARP协议。客户端广播ARP请求,当与该IP地址匹配的机器收到该ARP请求时,会以单播的方式发送ARP响应,响应中携带自己的MAC地址。
获取到MAC地址后,会存储到本地的ARP缓存中。
然后就会在IP协议包头的外面再包一层MAC头部,里面包含自己的MAC地址和下一跳(路由器)的MAC地址。
然后就可以把该数据包发给交换机,由交换机转发到路由器。
交换机
交换机接收到一个数据包时,会查看下一跳MAC地址。然后在自己本地的MAC地址表中进行匹配,从匹配到的MAC地址的特定交换机端口发送出去,就可以到达下一跳地址对应的节点。
如果下一跳MAC地址在交换机的MAC地址中不匹配,则会通过广播的方式把数据包从除源端口以外的所有交换机端口发送出去。
路由器
经过交换机的转发,我们的数据包就到了我们局域网的路由器。路由器发现下一跳MAC地址与自己的MAC地址匹配,会接收该数据包。
然后路由器会拆掉外层的MAC头部,得到里面的目标IP地址,然后在路由器本地的路由表进行匹配,然后得到匹配到的下一跳IP地址,把数据包发到外网。
发送数据包到外网前,要给数据包包装一个MAC头部。原来的MAC头部已被路由器拆掉,现在要以路由器自己的MAC地址为当前节点MAC地址,路由器的路由表匹配到的下一跳的节点对应的MAC地址为下一跳MAC地址,包装一个MAC头部。如果路由器不知道该IP地址对应的MAC地址,也是通过ARP协议获取。
就这样,数据包在互联网上经过多个路由器节点的网间路由,最终到达目标服务器所在的局域网。