访问网页的全过程

整个过程可以概括为几下几个部分:

  1. 域名解析成IP地址;
  2. 与目的主机进行TCP连接(三次握手);
  3. 发送与收取数据(浏览器与目的主机开始HTTP访问过程);
  4. 与目的主机断开TCP连接(四次挥手);

 

一、DNS解析成IP地址

  当一个用户在地址栏输入www.baidu.com时,DNS解析大致有以下几个过程:

  1.浏览器首先检查自身缓存中有没有解析过的这个域名对应的ip地址,如果命中,解析结束,返回ip地址。如果没有命中,进入过程2。

  2.浏览器会继续检查系统缓存中有没有对应的解析过的结果,windows中可通过hosts文件来设置,如果命中,返回ip地址,如果没有命中,进入过程3。

  3.主机会继续请求本地域名服务器(LDNS)来解析这个域名,查询方式是递归查询。如果命中,返回ip地址,如果没有命中,进入过程4。

  4.本地域名服务器(LDNS)会向根域名服务器(root name server)发起请求,查询方式为迭代查询,根域名服务器会告诉本地域名服务器应该去   .com顶级域名服务器中查询。

  5.本地域名服务器(LDNS)会向.com顶级域名服务器发起请求,迭代查询,如果命中,返回ip地址,如果没有命中,.com顶级域名服务器会告诉本地域名服务器下一步应向baidu.com权限域名服务器进行查询,过程6。

  6.本地域名服务器会向baidu.com权限域名服务器进行查询,迭代查询,如果命中,返回ip地址,如果没有命中,DNS解析失败。

 

  具体过程如下图:

 

二、与目的主机进行TCP连接(三次握手)

  先是客户端发起请求过程:

  1.应用层发起HTTP请求

  2.传输层TCP协议为传输报文提供可靠的字节流服务,使用了TCP三次握手。

  3.网络层是把TCP分割好的各种数据包传送给接收方。而要保证确实能传送到接收方还需要接收方的MAC地址,也就是物理地址。

  4.最后链路层将数据发送到数据链路层传输。至此请求报文已发出,客户端发送请求的阶段结束。

  服务端接收请求处理阶段:

  原路进行处理:链路层、网络层、传输层、应用层,然后响应客户端发送报文。

  TCP三次握手原理图:

  

  第一次握手:建立连接时,客户端向服务器发出连接请求报文段,这时首部中的同部位SYN=1,同时选择一个初始序号seq=x,并进入SYN_SENT状态,等待服务器确认。SYN是同步序列编号(synchronize Sequence Numbers)。

  第二次握手:B收到连接请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中将SYN位和ACK位都置1,确认号是ack = x +1,同时为自己选择一个初始序号seq=y,然后服务器B从LISTEN变为SYN_RCVD状态。

  第三次握手:客户端收到服务器的确认后,还要向B给出确认,确认报文段的ACK置1,确认序列号ack=y+1,seq=x +1。客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

 

三、发送与收取数据(浏览器与目的主机开始HTTP访问过程)

  只有建立连接后才能开始传输数据。

    1.浏览器向域名发出GET方法报文(HTTP请求);

    2.该GET方法通过TCP -> IP(DNS) -> MAC(ARP) -> 网关 -> 目的主机;

    3.目的主机收到数据帧,通过IP -> TCP -> HTTP,HTTP协议单元会回应HTTP协议格式封装好的HTML形式数据(HTTP响应);[从请求信息中获得客户机想访问的主机名。从请求信息中获取客户机想要访问的web应用(web应用程序指提供浏览器访问的程序,简称web应用)。从请求信息中获取客户机要访问的web资源(web资源指的是各种文件,图片,视频,文本等)。读取响应的主机下的web应用,web资源。用读取到的web资源数据,创建一个HTTP响应。]

    4.该HTML数据通过TCP -> IP -> MAC ->(ARP) -> 网关 -> 我的主机;

    5.我的主机收到数据帧,通过IP -> TCP -> HTTP -> 浏览器,浏览器以网页形式显示HTML内容。

 

四、与目的主机断开TCP连接(四次挥手)

  四次握手原理图:

 

    第一次挥手:客户端A、服务器B均处于ESTABLISHED状态。A的应用进程先向TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。A把连接释放报文段首部的终值控制位置1,其序列号seq=u,它等于前面已传送过的数据的最后一个字节的序列号加1,此时,客户端A进入FIN-WAIT-1(终止等待1)状态,等待B的确认。TCP规定,FIN报文段即使不携带数据,它也消耗一个序号。

    第二次挥手:服务器B收到连接释放报文段后即发出确认,确认号是ack=u+1,而这个报文段自己的序号是v,等于服务器B前面已传送过的数据的最后一个字节的序号加1,。然后B就进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时的TCP连接处于半关闭的状态(half-close),即A已经没有数据要发送了,但B若发送数据,A仍要接受。也就是说,从B到A这个方向的连接并未关闭,这个状态可能会持续一段时间。A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。

    第三次挥手:若B已经没有向A发送的数据,其应用进程就通知TCP释放连接。这时B发出的连接释放报文段使FIN=1。假定B的序列号为w(在半关闭状态B可能又发送了一些数据)。B还必须重复上次已发送过的确认号ack=u+1。这时B就进入LAST-ACK(最后确认)状态,等待A的确认。

    第四次挥手:A在收到B的连接释放报文段后,必须对此发出确认。在报文段中把ACK置1,确认号ack=w+1,而自己的序列号是seq=u+1(根据TCP标准,前面发送过的FIN报文段要消耗掉一个序号)。然后进入到TIME-WAIT(时间等待)状态。请注意,现在TCP连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer

)设置的2MSL后,A才进入到CLOSED状态。时间MSL叫做最长报文段寿命,一般为2分钟, 对于现在的网络,可根据具体情况使用更小的MSL值。B只要收到A发出的确认,就进入CLOSED状态。

 

常见面试题

    问题1:为什么连接的时候是三次握手? 

    主要是为了防止已失效的连接请求报文段突然又传到了B,产生错误。

    假定TCP连接只需要两次握手,A发出的一个请求a在某些网络节点长时间逗留,然后A又重新发送请求,B接收到后建立TCP连接,数据交换后,连接释放。这时,A发出的逗留的请求a到达B,本来请求a已经失效,但B收到之后,误认为A又发出一次新的连接请求。于是就向A发出确认报文段,同意连接。假定只有两次握手,那么只要B发出确认,新的连接就建立了,由于现在A没有发出建立连接的请求,因此不会理睬B的确认报文段,也不会向B发送数据。但B却认为新的传输连接已经建立了,并一直等待A发来的数据。B的许多资源就这样白白浪费了。采用三次握手的方法,可以防止上述现象的发生,例如A不会向B的确认发出确认,B由于收不到确认,就知道A并没有要求建立连接。

    问题2:为什么断开的时候是四次挥手?

    因为当服务器收到客户端的SYN连接请求的时候,可以直接发送SYN+ACK报文,其中ACK报文是用来应答的,SYN报文是用来同步的。但是断开的时候,当客户端收到FIN报文时,很可能并不会立刻关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,你发的FIN报文我已经收到了,只有等我服务器端所有的报文发送完,我才能发送FIN报文,因此不能一起发送。

    问题3:为什么TIME_WAIT状态需要经过3MSL才能返回到CLOSE状态?

    当四次挥手发送完毕,应该直接进入CLOSE状态,但是我们必须假定网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT就是用来重发可能丢失的ACK报文。第四次挥手客户端发送的ACK肯呢过会丢失,如果丢失,服务器没有收到ACK,将不断重复发送FIN报文段,所以客户端不能关闭,他必须确认服务器收到了最后的ACK。客户端在发出ACK后进入TIME_WAIT状态,客户端会设置一个计时器,等待2MSL的时间,如果在该时间内收到服务器发来的FIN报文,那么客户端会重发ACK,并重置计时器,直到2MSL时间内没有收到FIN报文,2MSL就是一个发送一个回复所需的最大时间。如果直到2MSL结束,客户端都没有再收到FIN报文段,客户端就会推断ACK已经被成功接收,则结束TCP连接。  

 

转载出处:https://blog.csdn.net/qq_38950316/article/details/81087809 

 

posted @ 2019-04-01 22:57  开发小拉拉  阅读(996)  评论(0编辑  收藏  举报