关于HTTP的三次握手与四次挥手

关于HTTP的三次握手与四次挥手,是一个老生常谈的问题了,觉得可以做个总结,加深一下自己的印象。也希望能够方便别人

首先简单说明一下TCP报文的首部,如下所示。

有两个序列号一个是sequence number,另一个是acknowledge number;另外还有6个标志位:SYN-同步标志,ACK-承认链接标志,FIN-结束标志,RST-复位标志,PSH-push操作标志,URG-TCP的紧急指针域


HTTP的三次握手

用两张图来说明,形象+正式


第一次握手: 客户端发送一个TCP包,将报文首部的SYN标志设为1,表示自己希望能与服务器端连接,同时将初始序列号(sequence number)X保存在报文的序列号中一起发送过去,客户端进入SYN_SEND状态,等待服务器端确认。

第二次握手: 服务器端发送一个TCP包,将报文首部的ACK标志设置为1表示承认连接,应答域有效,同时SYN标志也为1.将确认序列(acknowledged number)设置为x+1;序列号(sequence number)设置为y。此时服务器端进入SYN_RECV状态,等待客户端回复

第三次握手: 客户端发送确认包,将ACK标志为1,将服务器发送过来的序列号(sequence number)+1放在首部的Acknowledged number(确认号码)=y+1,序列号(sequence number)设置为x+1, 至此客户端和服务器端的连接就建立了。二者进入了established状态


HTTP的四次挥手

用两张图来说明,形象+正式


四次挥手,可以由任意一方发起第一次挥手

第一次挥手: 主动方将序列号(sequence number)设为u以及将FIN标志设置为1的报文发送给被动方,主动方进入FIN–WAIT-1状态.表示说没有数据要发送了。

第二次挥手: 被动方将主动方将确认序列号(Acknowledged number)设置为被动方发过来的序列号(sequence number)u+1,将新的序列号(sequence number)设置为v,同时将ACK设置为1,发送给主动方表示同意关闭连接。主动方进入FIN–WAIT-2状态.被动方进入COLSED_WAIT状态

第三次挥手: 被动方将FIN字段设置1,ACK设置为1,将确认序列号(Acknowledged number)设置为u+1,重置序列号(sequence number)w 发送给主动方,被动方进入LAST-ACK状态

第四次挥手: 主动方接受到了被动方发送的FIN=1标志,将确认序列号(Acknowledged number)设置为w+1,将序列号(sequence number)设置为u+1,发送为被动端。主动方进入TIME_WAIT状态,被动端接受到报文后关闭连接。主动端等待2MSL后没有收到回复,证明被动端成功关闭连接,主动端也把连接关闭了。


为什么要3次握手呢?

为了防止已经失效的连接请求报文突然又传送到了服务器,因而产生错误。主要是为了防止服务器端一直等待而浪费资源。比如说客户端A发送了一个报文连接到B,但是因为各种原因滞留了较长的时间,后来B收到了连接,就误以为A又发送了连接,就向A发出确认报文,同意连接,如果不采取三次握手,那么B直接确认发送数据,而A并没有建立相应的连接不搭理B的请求。但是B又等待着A的数据,那这样B端的资源就浪费了。

为什么要四次分手那四次分手又是为何呢?

TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当主动方发出FIN报文段时,只是表示主动方已经没有数据要发送了,主动发告诉被动方,它的数据已经全部发送完毕了;但是,这个时候主动方还是可以接受来自被动方的数据;当被动方返回ACK报文段时,表示它已经知道主动方没有数据发送了,但是被动方还是可以发送数据到主动方的;当被动方也发送了FIN报文段时,这个时候就表示被动方也没有数据要发送了,就会告诉主动方,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。如果要正确的理解四次分手的原理,就需要了解四次分手过程中的状态变化。

为什么等待2MSL(maximum segment lifetime,报文的最大生存时间)?
MSL通常为30s,1分钟或者2分钟1.
  1. 为了保证主动发送的最后一个ACK报文能够达到被动方,ACK报文段有可能丢失,因而使得处在在LAST-ACK状态下的被动方接受不到对方发送的ACK的确认段,那么被动方会超时重传这个FIN+ACK字段(第三次挥手的内容)。如果主动方不等待这个时间之间释放,就不会收到被动方再次发送的FIN+ACK,也不会再次发送确认报文,这样会导致被动方无法进入closed阶段2.
  2. 主动方在发送完ACK报文段后,再经过2MSL时间,就可以使得本连接持续的时间所产生的所有报文都从网络中消失。这样就可以使得下一个新的连接中不会在出现这种旧的连接请求的报文段


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页