TCP三次握手和四次挥手

Posted BGPY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP三次握手和四次挥手相关的知识,希望对你有一定的参考价值。

 

TCP的三次握手和四次挥手流程大家都很清楚,这里只对其中的某些细节进行学习。图1是三次握手与四次挥手的状态图

                   图1 TCP正常连接建立和终止所对应的状态

 

问题一:为什么是三次握手,而不是四次握手或者是二次握手
主要的解释有三点,逐一叙述:
1.由图1可以看到第二次握手其实是服务器的SYN与ACK一起发送的,如果让服务器分别发送SYN和ACK,这样就是四次握手了,
不过显然合并发送可以提高效率,所以就是三次握手,实质上是四次握手的优化
2. 需要三次握手主要是为了保证信道可靠,如果信道可靠,无论什么时候发出消息,对方一定能收的到,三次通信是理论上的最小值,
所以三次 握手不是TCP本身的要求,而是为了保证信道可靠
3.为了避免网络中存在延迟的重复分组
如果采用二次握手,只要服务器端发出ACK,新的连接就建立了。如果存在这样情况,如果之前在建立连接的时候,
存在客户端的SYN报文由于网络延迟原因没有发送 到服务端,直到之前的连接释放的某个时间才到达服务端,此时服务器收到失效的SYN报文,
就以为客户端再次发送的一个新的连接请求,如果是二次握手的话,这样 就建 立起连接,但是实质上客户端没有发送ACK,
因此没有理睬服务器的确认,也不会向服务器发送数据。这样服务器还在苦苦等等客户端发送数据过来,这样服务器就 白白浪费很多资源。

 

问题二:三次握手中如果有发包失败怎么办?
1. 第一个包,即A发送B的SYN包中途被丢,没有到达B
---> A会周期性超时重传,直到收到B的确认
2.第二个包,即B发给A的SYN和ACK中途被丢,没有到达A
----> B会周期性超时重传,直到收到A的确认
3.第三个包,即A发给B的ACK中途被丢,没有到达B
-->此时A发送完ACK,单方面认为TCP已经建立了,但是B没有认为连接建立了。
①:如果此时没有数据发送,B会周期性重传SYN和ACK,直到收到A的ACK为止
②:A发送完ACK,单方面认为连接已经建立,假定A有数据发送,B收到A的DATA+ACK。自然就可以建立连接了,也就可以接受DATA了
③:B如果有数据发送,数据发送不了,所以也会超时重传SYN和ACK

 

问题三:四次挥手中客户端收到服务器的FIN后,处于TIME_WAIT状态,也叫2MSL状态 在这个状态等候2MSL时间有什么用处呢,为什么要等待2MSL时间?

1:可靠的实现TCP全双工连接的终止
存在这种情况,如果客户端收到服务器的FIN以后,发送FIN的ACK给服务器,但是服务器没有收到
这个ACK,服务器会超时发送FIN,如果客户端不等待一段时间,将收不到重发的FIN,就不会重发
ACK,这样就不能正确的关闭连接,那等待多久比较合适呢?首先服务器有一个超时时间,如果在这个
超时时间内,收到了客户端的ACK,就可以正常关闭,如果收不到,就会重传FIN,所以这两段时间加起来就是
服务器的timeout+FIN的传输时间,为了保守起见,采用更加保守的等待时间2MSL,如果2MSL时间内没有收到
服务器的FIN,那就说明服务器端正确收到ACK了,如果收到了服务器的FIN呢,就客户端就重新发送ACK,这时候
客户端又会等待2MSL时间。(MSL Maximum Segment Lifetime任何报文段被丢失前在网络内的最长时间)
2: 允许老的重复字节在网络中消逝。

关闭一个TCP连接后,过段时间后用相同的地址和IP建立另一个连接,新连接称为老连接的
化身,因为他们的IP地址和端口号都相同,TCP必须防止来自前一个连接的老的重复分组在该连接终止后再出现。
因为有可能目前的连接所用的端口和IP在连接断开后立即建立新的连接,新的连接和老的连接端口和IP都一样。如果
网络中存在旧连接的重复字节,那么TCP协议就认为重复字节是属于新连接的,这样就可能和新的数据包发生混淆。
为了因对这个问题,TCP不允许处于TIME_WAIT的状态的连接发起
新的化身。即不允许再使用处于TIME_WAIT阶段的连接的IP 端口号进行连接,既然TIME_WAIT状态的持续时间为2MSL
就可以保证让某个方向的分组最多存活MSL秒就被丢弃,另一个方向的应答报文最多存活MSL秒就被丢弃,
通过实施这个规则,我们就能保证每成功建立每个TCP连接时,来自老连接老的重复分组都已经在网络中消逝了

问题四:为什么关闭连接需要四次挥手?

四次挥手是TCP的半关闭造成的,所谓的半关闭就是TCP提供了连接的一端在结束他的发送后还能接受另一端数据的能力
TCP连接时全双工的,所以需要每个方向单独进行关闭,那么能将四次挥手中的第二步和第三步进行合并?这就变成了“三次挥手”了?
原因是有可能服务端发送ACK的时候还需要发送数据给客户端,所以不能同时发送ACK和FIN,只能先将ACK发送到客户端
等服务端发送完数据以后,再发送FIN到到客户端

 

以上是关于TCP三次握手和四次挥手的主要内容,如果未能解决你的问题,请参考以下文章

TCP的三次握手和四次挥手

TCP三次握手和四次挥手

TCP三次握手和四次挥手

TCP-三次握手和四次挥手简单理解

图解TCP的三次握手和四次挥手(简单明了)

关于TCP的三次握手和四次挥手及其衍生问题