Tcp连接的断开

Posted wangkaia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tcp连接的断开相关的知识,希望对你有一定的参考价值。

Tcp连接断开的四次挥手

  1 client端向server端发送FIN请求断开连接,client端进入FIN_WAIT_1状态,等待server端的ACK。此时客户端

不能发送数据,但仍然能够从server端读取数据。

  2 server端收到FIN并发送了ACK之后,进入close_wait状态,不能够在读取数据,但仍然能向client发送数据。

  3 client端收到了server端的ACK以后,进入FIN_WAIT_2状态,等待server端的FIN。server端发送FIN后进入

LAST_ACK状态,等待client端的ACK。

  4 client端收到了server端FIN之后,并发送ACk之后,client端进入TIME_WAIT状态,等待2MSL。目的有两个

首选防止发送给server的ACK包丢失,确保连接正常关闭,第二个就是让重读的迷途分节在网络当中消逝。为了防止

过多的time_wait()状态描述符占用大量的资源,一种方法就是将处于time_wait()状态下的套接字设置为可重用的。

                                         四次挥手的过程

技术图片

 

常见问题:

1为什么连接的时候是三次握手,关闭的时候却是四次握手?

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

2为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

  虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

3为什么不能用两次握手进行连接?

 3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
     现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

4 如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

以上是关于Tcp连接的断开的主要内容,如果未能解决你的问题,请参考以下文章

TCP的连接与断开

TCP的连接与断开

tcp长连接保持多久

详解TCP四次挥手(断开TCP连接过程)

怎样强制断开TCP连接

TCP连接的建立和断开