1:概览
从大致上讲:
客户端获取URL - > DNS解析 - > TCP连接 - >发送HTTP请求 - >服务器处理请求 - >返回报文 - >浏览器解析渲染页面 - > TCP断开连接。
2:详细步骤
2-1:浏览器根据域名查询域名对应的服务器的IP地址
查找顺序如下:浏览器DNS缓存 - > 操作系统DNS缓存 - > 路由器缓存 - > 本地(ISP)域名服务器缓存 - > 根域名服务器。
- 浏览器缓存:首先是查找浏览器缓存,浏览器会缓存DNS记录一段时间,不同浏览器保存的时常不等(2分钟到30分钟不等)。
- 系统缓存:如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用来查找这个网址的对应DNS信息。
- 路由器缓存:如果在系统缓存里没有找到找到对应的IP,请求会发向路由器,它一般会有自己的DNS缓存。
- ISP DNS服务器:如果在路由器缓存里还是没有对应的IP,请求会被发送到ISP。
- 根域名服务器:如果还是没有,请求将发向根域名服务器进行搜索。找不到就说明此域名不存在。
2-2:浏览器主机根据IP地址与服务器建立TCP连接
建立TCP连接需要进行三次握手:
- 浏览器主机 - > 服务器:SYN = 1,seq = x;
主机发出连接请求报文段,报文首部中的同步位:SYN = 1,初始序号 seq = x。SYN报文段不能携带数据,但是要消耗一个序号。 - 服务器 - > 浏览器主机:SYN = 1,ACK = 1,seq = y,ack = x+1;
服务器接收后,如果确认连接,向浏览器发送确认报文。确认报文中的 SYN 和 ACK 都为 1。确认号 ack = x + 1,自己的初始序号 seq = y。这个报文段也不能携带数据,但同样要消耗一个序号。 - 浏览器主机 -> 服务器:ACK = 1,seq = x+1,ack = y+1。
客户端接收到服务端的确认后,再给服务端给出确认。确认报文段的ACK为1,确认号 ack = y + 1,而自己的序号为 x + 1。ACK报文段可以携带数据,但如果不携带数据则不消耗序号。
通俗的说法:
Client:嘿,Server,是我,听到了吗?
Server:我听到了,你能听到我的吗?
Client:好的,我们互相都能听到对方的话,我们的通信可以开始了。
三次握手其实是在一次握手过程中交换了三个报文(就像两个人第一次见面进行一次握手时,手上下摇晃了三次,而并非是进行了三次握手。在 《计算机网络》-谢希仁 第7版中使用三报文握手代替三次握手。
2-2-1:为什么需要三次握手
在这本书中也提到了为什么需要三次握手?主要是为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。
举例如下:
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。
本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。
由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
而TCP 为什么三次握手而不是两次握手(正解版)提出另一种说法是:
为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认
2-3:浏览器将访问请求封装为一个HTTP请求报文,通过TCP协议发送给服务器
请求报文由请求行(request line)、请求头(header)、请求体三个部分组成。
参考HTTP协议
2-4:服务器处理请求并返回 HTTP 报文
即MVC后台处理+HTTP响应报文
2-5:浏览器解析渲染页面
在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了,如果是个静态的页面,拿到此就基本结束了。如果是是动态的,那么在浏览器显示HTML时,会获取嵌入在HTML中的对象,浏览器会发送获取请求来重新获得这些文件。这些请求都要经历一个和HTML读取类似的过程。
对于静态的页面内容,浏览器通常会进行缓存,而对于动态的内容,浏览器通常不会进行缓存。
2-6:浏览器异步请求其他资源
在分析HTML时,若发现网页引用了其他资源,例如:css、图片等,浏览器则发起HTTP请求,得到响应资源。
2-7:断开连接
当数据传送完毕,需要断开 tcp 连接,此时发起 tcp 四次挥手。
建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
TCP 连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务端均可主动发起挥手动作。
刚开始双方都处于ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:
- 第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
即发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。 - 第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。 - 第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。 - 第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
收到一个FIN只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入TIME_WAIT是正常的,服务端通常执行被动关闭,不会进入TIME_WAIT状态。
通俗的说法
Client:我所有东西都说完了
Server:我已经全部听到了,但是等等我,我还没说完
Server:好了,我已经说完了
Client:好的,那我们的通信结束
2-7-1:为什么需要四次挥手
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。
2-7-2:四次挥手释放连接时,等待2MSL的意义
MSL:最长报文段寿命
两个理由:
- 保证客户端发送的最后一个ACK报文段能够到达服务端。
这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,服务端超时重传FIN+ACK报文段,而客户端能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重新启动2MSL计时器,最后客户端和服务端都进入到CLOSED状态,若客户端在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到服务端重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则服务端无法正常进入到CLOSED状态。 - 防止“已失效的连接请求报文段”出现在本连接中。
客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
3:这个过程需要哪些协议
- DNS协议。获取域名对应IP
- TCP协议。与服务器建立TCP连接
- IP协议。建立TCP协议时,需要发送数据,发送数据在网络层使用IP协议
- OPSF协议。IP数据包在路由器之间,路由选择使用OPSF协议
- ARP协议。路由器在与服务器通信时,需要将ip地址转换为MAC地址,需要使用ARP协议
- HTTP协议。在TCP建立完成后,使用HTTP协议访问网页