TCP协议中的三次握手四次挥手问题

Posted yuanzhijing

tags:

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

一、三次握手建立连接详解:

(1)当客户端向服务器发起连接请求时,客户端会发送同步序列标号SYN J到服务器,等待服务器确认,这时客户端的状态为SYN_SENT;

(2)当服务器收到客户端发送的SYN J,服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1,这时服务器的状态为SYN_RECV;

(3)客户端收到服务器发送的SYN和ACK包后,再向服务器发送一个确认ACK K+1,发送完毕后,客户端和服务器端的状态为establish,即TCP连接成功。

总结:三次握手发生在套接口的哪几个函数中呢?

      服务器必须准备好接受外来的连接,这通过socket、bind和listen函数来完成,称为被动打开。

      客户端通过调用connect进行主动打开。这引起客户端向服务器发送了SYN J分节,这时connect进入阻塞状态。

      服务器监听到连接请求,即受到SYN J分节,调用accept函数接受请求,并向客户端发送SYN K、ACK J+1分节,这时accept进入阻塞状态。

      客户端收到服务器的SYN K、ACK J+1分节之后,这时connect返回,并对SYN K分节进行确认,服务器收到ACK K+1分节时,accept返回,至此三次握手完毕,连接建立。

      户端的connect在三次握手的第二次返回,而服务器端的accept在三次握手的第三次返回。

二、四次挥手释放连接详解:

(1)A端首先调用close执行主动关闭,向B端发送一个FIN分节,表示数据发送完毕;

(2)B端接收到A端发送的FIN后,执行被动关闭,对这个FIN进行确认;

(3)一段时间后,B端调用close关闭它的套接口,这导致它的TCP向A端发送一个FIN;

(4)A端接收到B端发送的FIN后,向B端发送确认ACK,然后经过两个MSL时长后断开连接。

MSL是Maximum Segmeng Lifetime,最大报文段生存时间,2个MSL是是报文段发送和接收的最长时间。

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次挥手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步挥手。

【问题2】TCP为什么采用3次握手来建立连接,若采用2次握手可以吗?请说明原因。

答:不可以。采用三次握手是为了防止失效的连接请求报文段突然又传送到服务器,从而发生错误。当客户端发出的连接请求报文段由于某些原因没有及时到达服务器,而客户端在等待一段时间后,又重新向服务器发送连接请求,且建立成功,顺序完成数据传输,那么第一次发送的连接请求报文段就成为失效的连接请求报文段。

      考虑这样一种特殊的情况,客户端第一次发送的连接请求并没有丢失,而是因为网络问题导致延迟到达服务器。服务器以为是客户端又发起的新连接,于是服务器同意连接,并向客户端发回确认,但是此时客户端不予理会,服务器就会一直等待客户端发送数据,导致服务器的资源浪费。

【问题3】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态一是用来重发可能丢失的ACK报文,实现终止TCP全双工连接的可靠性;二是保证当成功建立一个TCP连接时,来自该连接先前的化身的老重复分组都已经在网络中消失了。



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

TCP协议中的三次握手和四次挥手

揭秘——TCP的三次握手和四次挥手

一文搞懂TCP的三次握手和四次挥手

python网络编程-TCP协议中的三次握手和四次挥手(图解)

聊聊TCP协议的三次握手和四次挥手

TCP 协议TCP的三次握手和四次挥手