为啥是四次挥手而不是三次
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥是四次挥手而不是三次相关的知识,希望对你有一定的参考价值。
参考技术A 为什么是四次挥手而不是三次?因为服务端在接收到FIN, 往往不会立即返回FIN, 必须等到服务端所有的报文都发送完毕了,才能发FIN。因此先发一个ACK表示已经收到客户端的FIN,延迟一段时间才发FIN。这就造成了四次挥手。
如果是三次挥手会有什么问题?
等于说服务端将ACK和FIN的发送合并为一次挥手,这个时候长时间的延迟可能会导致客户端误以为FIN没有到达客户端,从而让客户端不断的重发FIN。
参考资料
http://47.98.159.95/my_blog/tcp/003.html#%E8%BF%87%E7%A8%8B%E6%8B%86%E8%A7%A3
关于TCP的三次握手和四次挥手及其衍生问题
文章目录
关于TCP的三次握手和四次挥手及其衍生问题
TCP三次握手
过程
- 第一次握手,客户端向服务器发送请求连接的报文,SYN=1,序列号seq=x;表示自己想要和服务器之间建立TCP连接,此时客户端就会进入连接发送的状态。
- 第二次握手,服务器接收到客户端发送来的连接请求报文,先开启一个socket的端口,端口开启之后,向客户端发送一个确认信号,ACK=1,序列号seq=y,ack=x+1。
- 第三次握手,客户端接收到服务器发送来的确认,知道服务器可以和自己建立连接,最后想服务器发送一个确认信息,ACK=1,ack=y+1,seq=x+1
图解示意
四次挥手
挥手过程
- 第一次挥手,客户端向服务器发送连接释放的报文FIN=1,以及序列号Seq=u,客户端停止向服务器发送数据,但是客户端依旧要接收服务器发送过来的数据,此时客户端就进入了第一阶段的等待状态。
- 第二次挥手,服务器接收到客户端发送来的连接释放报文,向客户端做出确认回应,但是暂时不发送连接释放报文,只发送ACK=1,序列号Seq=v,ack=u+1,服务器通知上层应用进程,然后继续向客户端发送遗留数据,此时服务器进入关闭等待状态,客户端进入关闭等待2状态。
- 第三次挥手,当服务器将数据发送完毕的时候,向客户端发送连接释放报文FIN=1,以及确认号ACK=1,序列号Seq=w,ack=u+1,此时服务器等待客户端的最后一次确认。
- 第四次挥手,客户端收到服务发送来的连接释放报文,向服务器发送最后一次确认,ACK=1,ack=w+1,Seq=u+1,此时服务器收到客户端的确认之后立即进入关闭状态,但是客户端没有立即断开连接,而是等待了2*MLS时长,最长报文段寿命。然后才正式进入到关闭状态。
图解示意
相关衍生问题
为啥子需要最后一次的确认(三次握手次数不能减少的原因)
- 不能减少握手,或者说要有最后一次确认的原因是防止已经客户端发出后已经失效的连接又重新传回到服务器,导致资源浪费,造成相关不必要的错误
- 举个例子:比方现在客户端向服务器发送了一次请求连接的报文,但是由于网络状况不佳,或者服务器宕机,导致服务器迟迟没有收到这个请求,此时客户端就会再次发送请求,然后服务器收到做确认,但是过了一段时间,最开始没有到达服务器端的连接请求,到达了服务器端,如果是两次握手机制,那么就会就又会建立一次连接,这样就造成了不必要的连接导致资源浪费。
- 采用TCP三次握手,通过最后一次确认机制,检测是否已经建立连接,就可以减少这样的资源浪费。
为什么我握手是三次,挥手是四次
- TCP协议是一个全双工的通信模式,他是端到端进行双方互相传输和接收数据的,之所以是四次挥手是因为,当客户端向服务器发送释放连接报文的时候,客户端是主动的,而服务器是被动的,服务器向进行确认但是没有发送释放连接报文,因为此时客户端数据发送完毕,但是服务器还没有发送完毕,所以客户端必须等待并接收服务器将数据发送完毕,数据发送完毕服务器才会发送释放连接报文,然后客户端进行确认,服务器立即关闭,客户端等待一段时间后关闭。
- 实际上就是前两次挥手关闭客户端方向的数据传输,后两次连接关闭服务器方的数据连接。
为什么客户端最后要等待一段时间才断开连接
- 这因为虽然双方都同意关闭连接了,而且相关的数据报文都发送完毕,按道理可以直接回到关闭状态,但是我们需要考虑一种情况就是网络不稳定的情况,我们需要保证最后一次确认的ACK报文一定要让服务器接收到,因为服务器发送完释放连接报文后处于的是LAST-ACK状态,如果说你你发送ACK报文后你立马关闭了,这个ACK报文因为网络原因一直没有发送到服务器上,这样就会导致,服务器一直等待关闭不了,所以客户端才会等待最长报文寿命时间,以防止出现ACK不能正常传输给服务器的情况。
以上是关于为啥是四次挥手而不是三次的主要内容,如果未能解决你的问题,请参考以下文章