Web页面请求的全过程
场景:
小李刚入职行政人员为他分配了工作电脑,小李用一根网线将电脑连接至工位的交换机上,交换机又与公司的路由器相连,如下图所示。公司的路由器与ISP网络连通,CMNET为中国移动的ISP网络,CMNET为公司提供了DNS服务,DNS服务器驻留在CMNET网络中。
假设:DHCP服务器运行在公司路由器上
请求过程:
-
IP分配
-
电脑启动后,操作系统封装DHCP应用报文,传输层使用UDP协议的68号客户端端口进行发送,目的地为DHCP服务器的67号端口,传输层将源端口和目标端口放在报文段的头部。
-
因此此时电脑还没有IP地址,网络层将该UDP报文段放在一个IP分组中,该分组的目的IP是广播地址255.255.255.255,源IP地址为0.0.0.0。
-
链路层将IP分组封装成帧,在以太网帧的头部,源MAC地址为0D:16:A1:68:92:8A,由于还没有IP,更不知道下一跳的MAC地址,所以链路层将该帧的目的MAC地址设置为FF:FF:FF:FF:FF:FF(广播地址),使该帧将被广播到所有与公司交换机相连的设备。
-
交换机收到以太网帧,发现其目的MAC地址为FF:FF:FF:FF:FF:FF,则在所有出口广播该帧,公司路由器当然也会收到该帧。
-
路由器收到来自交换机的帧后,解析出IP分组交由网络层,网络层发现该IP分组头部的目的IP地址是广播地址,便知道它也需要处理这个请求,于是从IP分组中抽取出UDP报文段,交由传输层进行处理。UDP将DHCP的请求报文上传给应用层68号端口对应的DHCP服务,至此DHCP服务器收到了来自新进主机的DHCP请求报文。
如果该路由器上没有DHCP服务器的话,它会记录一台DHCP服务器地址,该路由器作为中继,将DHCP的请求路由到DHCP服务器。
-
假设公司路由器与CMNET的ISP网络连接的子网块为 172.168.81.0/24,路由可以在该范围内分配IP地址。公司使用的所有IP地址都在CMNET的地址块中,假设DHCP服务器为小李的电脑分配了172.168.81.24地址。DHCP服务器生成包含该IP地址、DNS服务器地址(172.162.72.16)、默认网关路由器的IP地址(172.168.81.1)和子网块(172.168.81.0/24)的DHCP ACK响应报文。该报文被封装在一个UDP报文段中,其中目的端口为67(DHCP客户端端口),UDP报文段被放在一个IP分组中,其中源IP地址为172.168.81.1,目的IP地址为255.255.255.255(广播响应)。该IP分组又被放在一个以太网帧中,帧中的源MAC地址为路由器连接到交换机的接口的MAC地址80:A3:72:F1:B2:65,目的MAC地址为小李电脑的MAC地址0D:16:A1:68:92:8A。
-
路由器将包含DHCP ACK响应报文的数据帧发送给交换机,由于交换机具有自学习的能力,在先前小李的电脑通过交换机发送帧时,交换机已经将小李电脑的MAC地址和交换机的入口作为表项存储在转发表中,所以当交换机收到DHCP ACK的响应帧时,查看帧头的目标MAC地址0D:16:A1:68:92:8A,便知道该帧仅从通向小李电脑的输出端口转发
-
小李的电脑收到DHCP ACK的报文后,依次从帧中提取IP分组,从IP分组提取UDP报文段,再从UDP报文段提取响应报文,这时DHCP客户端还需要向DHCP服务器发送确认报文表示收到了分配的相关IP地址信息并选择使用(依然采用广播IP),DHCP服务端再次客户端发送ACK确认报文,至此才成功获取到了IP地址。电脑的DHCP客户端记录它的IP地址和DNS服务器地址,还要在路由表(IP转发表)填充默认路由网关的地址,从此,小李将向默认网关发送目的地址为其子网72.168.81.0/24以外的数据报。
-
-
DNS和ARP
小李在浏览器输入www.baidu.com,电脑需要知道该域名对应的IP地址,生成一个TCP套接字,然后套接字向www.baidu.com发送HTTP请求。可以使用DNS域名解析系统获取www.baidu.com域名对应的IP地址
-
操作系统生成一个DNS查询报文,将域名www.baidu.com放在报文的问题段中。该DNS报文被放在一个目的端口为53的UDP报文段中,UDP报文段又被放在一个IP分组中,源IP地址为172.168.81.24,目的IP地址为172.162.72.16(DNS服务器)。IP分组被封装在以太网帧中,源MAC地址为0D:16:A1:68:92:8A,该帧将发送给到公司的路由器中,但现在只知道路由器的IP地址,却不知道该网关路由器的MAC地址。为了获取路由器的MAC地址,将使用ARP协议。
-
小李电脑将生成一个目的IP地址 172.168.81.1(默认网关)的ARP查询报文,该ARP报文封装在一个目标MAC为FF:FF:FF:FF:FF:FF(广播地址)的以太网帧中,并向交换机发送该帧,交换机的链路层发现该帧的目的地址为广播地址,便将该帧发送给所有的连接设备,包括网关路由器。
-
网关路由器在于交换机相连的接口上收到了该ARP查询的帧,解析ARP报文,发现请求帧的目的IP地址与帧在路由器入口的IP地址一样,则组装一个ARP响应报文,标明它的MAC地址80:A3:72:F1:B2:65对应IP地址172.168.81.1,将报文封装在一个以太网帧中,发送给交换机,再由交换机发送给小李的电脑。
-
小李的电脑收到ARP响应的帧后,从响应报文中获取网关路由器的MAC地址(80:A3:72:F1:B2:65),至此,DNS查询的以太网帧头部目的MAC地址就有了。
-
小李的电脑将DNS查询报文发送到网关路由器,网关路由器根据目的IP地址,结合路由表,ARP表,转发表将包含DNS查询的帧转发到CMNET网络中左侧的路由器。
-
CMNET网络中左侧的路由器收到该帧,提取IP分组,检查IP分组的目的地址(172.162.72.16),根据其路由表表确定出接口,通过该接口朝着DNS服务器转发数据报,而转发表已经通过CMNET的域内协议(RIP、OSPF)以及域间协议(BGP)填写。
-
DNS查询报文的IP分组到达DNS服务器,从IP分组中提取UDP报文段,再从报文段获取DNS的查询报文,然后在DNS服务器的数据库中查找名字www.baidu.com,找到域名对应IP地址的DNS源记录(如果缓存中有的话)。如果该DNS服务器没有缓存,则去权威域名服务器(baidu.com)查找,如果还没有,则去根域名服务器com查找(根域名服务器一定有)。该DNS服务器封装一个主机名(域名)到IP地址映射的DNS响应报文,将该DNS响应报文封装在UDP报文段,在放入IP分组中,将数据报发送到公司的路由器,在经交换机发送到小李的电脑,小李电脑从DNS响应报文中获得服务器www.baidu.com的IP地址68.233.125.8。
-
-
客户端-服务器交互:TCP和HTTP
小李的电脑现在已经有了www.baidu.com的IP地址68.233.125.8,可以生成TCP套接字,向该服务器发送HTTP GET请求- 生成TCP套接字的时候,需要进行三次握手,首先生成一个随机的初始序列号seq = client_seq,然后在TCP报文段的头部填充目的端口80,同时将标志位的SYN置为1,表示请求连接。然后将TCP报文段封装在IP分组中,头部的目的IP地址68.233.125.8,再将IP分组放入下一跳MAC地址为80:A3:72:F1:B2:65的以太网帧中,并向交换机发送该帧。
- 在公司网络、CMNET网络和百度网络中的路由器向www.baidu.com的服务器转发包含 TCP SYN的数据报,使用每台路由器中的路由表。
- 最终,浏览器发出的TCP SYN的连接请求报文发送到www.baidu.com的服务器,从IP分组中获取TCP SYN的请求报文,根据TCP头的目的端口与相应的服务器套接字相关联,服务器封装一个TCP SYNACK的相应报文,其中相应报文的头部包含标志位SYN = 1,确认号ack = client_seq(请求报文头中的)+1,序列号seq = server_seq(服务器随机生成的初始化序号),将该TCP相应报文放入IP分组,再将IP分组放入链路层帧中,发给小李的电脑。
- 小李的电脑收到来自www.baidu.com的TCP SYN ACK 响应确认报文,客户端再封装对服务端的响应报文,报文头包括SYN=0(连接建立),ack=server_seq(服务端生成的)+1,seq = client_seq+1(服务端接收缓冲区等待接收的索引),按照第一次连接请求发送的方式,将客户端的响应ack发送给www.baidu.com的服务器。至此,TCP连接完全建立。
- TCP连接建立后,小李可以向www.baidu.com服务器发送请求了,浏览器生成HTTP GET报文并写入TCP套接字,HTTP GET的请求报文作为TCP报文段的载荷(数据部分),然后按照TCP请求连接的过程将请求报文发送到www.baidu.com服务器80号端口对应的套接字,HTTP服务器从套接字中获取HTTP GET报文,生成一个HTTP响应报文,将请求的Web页面的内容放入HTTP响应体中,并将报文发送进TCP套接字。
- 包含HTTP响应报文的数据报通过百度网络、CMNET网络、公司路由器和交换机到达小李的电脑,浏览器从套接字读取HTTP响应,从HTTP响应体中获取Web页面的html,由浏览器根据html绘制页面,至此,一个完整的页面显示在浏览器界面上。
- 最后TCP通过四次挥手断开连接,由客户端HTTP发起连接断开的请求,其中TCP报文段的头部标志位FIN = 1(连接断开请求),将TCP报文封装成帧发送到www.baidu.com的服务器,服务器发送连接断开的响应报文。TCP是全双工的连接,服务端向客户端发送连接断开的请求,报文头同上,客户端收到FIN的请求报文,发送ACK响应,然后进入到TIME_WAIT(30s)的状态,30秒内没有收到来自服务端的数据则连接正式关闭,客户端所有资源被释放。