在浏览器输入baidu.com后,敲回车会发生哪些技术步骤?
这里先讲一下发送请求的过程:
- 应用层:浏览器发送一个HTTP请求;
- 运输层:对从应用层发送过来的HTTP请求报文使用TCP协议或者UDP协议进行封装(将数据进行分割,在各个报文上打上标记序号和端口号)发送给网络层;
- 网络层:在网络层通过IP协议将ip地址和数据报封装为ip数据报,在进行封装的时候需要目的MAC地址,这个时候使用ARP协议来获取目的MAC地址(主机发送信息时会将包含目标IP地址信息ARP请求广播到网络上所有的主机,并接受返回消息,以此确定目标的物理地址,找到目的的MAC地址)
- 数据链路层:把网络层交下来的IP数据添加首部和尾部,封装为MAC帧,根据目的MAC地址建立TCP连接(三次握手)
1.域名解析
1.查看浏览器缓存里面是否存在url对应的ip地址,如果有,则返回,否则进行下一步;
2.查看本地的host文件里面是否存在url对应的ip地址,如果有,则返回,否则进行下一步;
3.将域名发送到本地域名服务器,在本地域名服务器的的DNS缓存里面进行查找,如果有,则返回,否则进行下一步;
4.向DFS服务器查询url对应的ip地址
- 本地域名服务器向根域名服务器发送请求,根域名服务器返回com顶级域名服务器对应的ip地址;
- 本地域名服务器向com顶级域名服务器发送请求,顶级域名服务器返回baidu权威域名服务器对用的ip地址;
这里在运输层使用UDP协议
这个时候就知道了baidu.com的ip地址
2.发起TCP连接
在获取到ip地址之后就可以通过三次握手,在浏览器和服务器之间建立连接。
三次握手的本质是确认通信双方收发数据的能力
比如,我向朋友发送信息,他收到了我的信息,那么他就知道了我的发送能力和他接收能力是可以的;
于是,他又发送信息给我,我收到了,就知道他的接收能力和发送能力,以及我的接收能力和发送能力是可以的
但是,他不知道他自己的发送能力和我的接收能力到底可不可以,所以我再次向他发送信息表示我的接收能力和他的发送能力是可以的
- 第一次握手:客户端向服务端发送请求连接,首先客户端随机生成一个序列号ISN(100),那么客户端发送给服务端的报文段里就包括,标志位SYN(SYN=1),序列号seq=100;
- 第二次握手:服务端接收到客户端发送过来的请求,从报文里面的SYN标志位知道,这是一个建立连接的请求,服务端将客户端的起始序列号存起来,并随机生成一个服务的起始序列号(300),然后给客户端一个回复报文,报文里面包括,标志位SYN和ACK(SYN=1,ACK=1),ack=101(客户端发送的报文的起始序列号+1),seq=300;
- 第三次握手,客户端收到服务端回复的消息,发现ACK=1,ack=101,就知道服务端收到发送过去的那段起始序列号为100的那段报文,同时发现SYN=1,seq=300,知道服务端同意了这次连接,于是将服务端的起始序列号300存起来。然后客户端再向服务端回复一条报文,ACK标志位(ACK=1),ack=301(服务端起始序列号+1),seq=101(因为第一次握手时发送的报文占据了一个序列号,所以这次的序列号为101,需要注意的是不携带数据的ACK报文是不占据序列号的,所以后面第一次正式发送数据时seq还是101),当服务端收到报文后发现ACK=1并且ack=301,就知道客户端收到序列号为300的报文了,就这样客户端和服务端通过TCP建立了连接。
3.数据传送
握手成功后,开始通讯,浏览器发送一个请求,服务器接收到之后响应请求,将数据返回给浏览器,数据可以是根据html协议组织的网页,(里边包含页面的布局,文字等等,也可以是图片或者脚本程序等)如果资源路径指定的资源不存在,服务器就会返回404错误。如果返回的是一个页面,则渲染页面,并响应用户的操作,如果页面里又外链,则根据外链URL地址,重复解析URL。
4.窗口关闭,断开连接
四次挥手
比如客户端初始化的序列号ISN=100,服务端初始化的序列号ISN=300。TCP连接成功后客户端总共发送了1000个字节的数据,服务端在客户端发FIN报文前总共回复了2000个字节的数据。
- 第一次挥手:当客户端的数据都传输完成后,客户端向服务端发出连接释放报文(当然数据没发完时也可以发送连接释放报文并停止发送数据),释放连接报文包含FIN标志位(FIN=1)、序列号seq=1101(100+1+1000,其中的1是建立连接时占的一个序列号)。需要注意的是客户端发出FIN报文段后只是不能发数据了,但是还可以正常收数据;另外FIN报文段即使不携带数据也要占据一个序列号。
- 第二次挥手:服务端收到客户端发的FIN报文后给客户端回复确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=1102(客户端FIN报文序列号1101+1)、序列号seq=2300(300+2000)。此时服务端处于关闭等待状态,而不是立马给客户端发FIN报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。
- 第三次挥手:服务端将最后数据(比如50个字节)发送完毕后就向客户端发出连接释放报文,报文包含FIN和ACK标志位(FIN=1,ACK=1)、确认号和第二次挥手一样ack=1102、序列号seq=2350(2300+50)。
- 第四次挥手:客户端收到服务端发的FIN报文后,向服务端发出确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=2351、序列号seq=1102。注意客户端发出确认报文后不是立马释放TCP连接,而是要经过2MSL(最长报文段寿命的2倍时长)后才释放TCP连接。而服务端一旦收到客户端发出的确认报文就会立马释放TCP连接,所以服务端结束TCP连接的时间要比客户端早一些。
参考资料:
https://www.zhihu.com/question/34873227
https://www.cnblogs.com/wangxirui/p/12794765.html
https://blog.csdn.net/ThinkWon/article/details/104903925