TCP断开链接的四次握手

来源:互联网 发布:免费的群发短信软件 编辑:程序博客网 时间:2024/06/06 00:46

TCP是面连接的可靠传输,具有流量控制,拥塞控制的保证数据包按序到达的传输控制协议。


TCP是面向连接的,因此TCP数据传输的过程是:建立连接 、数据传输、断开连接。

1.建立连接:三次握手:

          client  ----syn----->  server : syn_received

          client <---ack\syn--  server:    syn_sent

          client  ----ack------>   server :  established.

2. 数据传输: 拥塞控制,流量控制、(停等协议, 慢启动、快恢复)等等,


3. 连接的断开:四次握手

           

状态迁移

1). SO_LINGER/ SO_REUSEADDR
 TCP正常的关闭过程如下(四次握手过程):
    (FIN_WAIT_1) A       ---FIN--->        B(CLOSE_WAIT)
    (FIN_WAIT_2) A       <--ACK--         B(CLOSE_WAIT)
    (TIME_WAIT)  A        <--FIN----       B(LAST_ACK)
    (TIME_WAIT)  A        ---ACK->        B(CLOSED)
    Ø  A端首先发送一个FIN请求给B端,请求断开连接,

        发送FIN请求后,  A端的TCP状态变为FIN_WAIT_1,

        接收到FIN请求后, B端的TCP状态变更为CLOSE_WAIT。


    Ø  B端接收到FIN请求后,B端回一个ACK给A端,确认接收到的FIN请求,

        A接收到ACK确认后,A端的TCP状态变更为为FIN_WAIT_2。


    Ø  B端接着再发送一个FIN请求给A端,

       与连接过程的3次握手过程不一样,这个FIN请求之所以并不是与上一个确认一起发送,

       之所以如此处理,是因为TCP是双通道的,允许在发送ACK请求后,并不马上发FIN请求,

       即只关闭A到B端的数据流,仍然允许B端到A端的数据流。

      这个FIN请求发送之后,B端的TCP状态变更为LAST_ACK,

      A端的状态变更为TIME_WAIT。


    Ø  A端接收到B端的FIN请求后,再回B端一个ACK信息,对上一个FIN请求进行确认,到此时B端状态变更为CLOSED,Socket可以关闭。
   


除了如上正常的关闭(优雅关闭)之外,TCP还提供了另外一种非优雅的关闭方式RST(Reset)
   (CLOSED) A         ---RST-->      B (CLOSED)
   Ø  A端发送RST状态之后,TCP进入CLOSED状态,B端接收到RST后,也即可进入CLOSED状态。


正常(优雅)关闭存在的问题 :   

在第一种关闭方式上(优雅关闭),非常遗憾,A端在最后发送一个ACK请求后,并不能马上将该Socket回收,

 因为A并不能确定B一定能够接收到这个ACK确认,因此A端必须对这个Socket维持TIME_WAIT状态2MSL.

(MSL=Max Segment Lifetime,取决于操作系统和TCP实现,该值为30秒、60秒或2分钟)。

如果A端是客户端,这并不会成为问题;但如果A端是服务端,那就很危险了,如果连接的Socket非常多,而又维持如此多的TIME_WAIT状态的话,那么有可能会将Socket耗尽(报Too Many Open File)。

    服务端为了解决这个问题,可选择的方式有三种:
    Ø  保证由客户端主动发起关闭(即B端为服务器)
    Ø  关闭的时候使用RST的方式(非优雅关闭)
    Ø  对处于TIME_WAIT状态的TCP允许重用
     一般我们当然最好是选择第一种方式,

实在没有办法的时候,我们可以使用SO_LINGER选择第二种方式,使用SO_REUSEADDR选择第三种方式

          

原创粉丝点击