Linux 下TCP链接关闭状况分析

1、TCP链接关闭的几种方式:shell

一、“正常”关闭:调用close()关闭socket、没close但进程正常结束(固然这是不该该的作法)、进程core掉、在shell命令 行中kill掉进程,均可抽象成“正常”关闭。由于即便core掉,内核也会立刻帮应用程序回收(close)socket文件描述符。服务器

     “正常”关闭,默认状况下(非默认即设置Linger下面会介绍),关闭端即客户端TCP层会发FIN包,对端即服务器TCP层收到后,回ACK,客户端 进入FIN_WAIT2状态。此时,TCP终止链接的4个分组中服务器应该发的第3个分组FIN包,其TCP层是不会主动发的,只有服务器端socket “正常”关闭,才会发出这个FIN包。至此,客户端进入TIME_WAIT状态。并发

二、“非”正常关闭:客户端崩溃了,此时确定发不出FIN包了(固然啦,内核都没机会帮应用程序回收资源了)。这种状况,服务器端有以下两种状况:socket

    A、服务器send数据,由于客户端已经崩溃,服务器收不到ACK天然会不停的重传。源自tcp

        Berkeley的重传机制,重传8次,相对第一次传的15分钟后仍没收到ACK,则返回函数

        ETIMEDOUT或EHOSTUNREAC错误。若是服务器不理会这个错误,再次调用send,则spa

        立马返回Broken Pipe错误。    orm

       注:15分钟超时能够在 /proc/sys/net/ipv4/tcp_retries2 中修改接口

   B、 服务器不发任何数据了,那只有靠应用层心跳检测机制或Keepalive,来发觉TCP断连了。进程

2、SO_LINGER套接口选项

           A、l_onoff设置为0,这也是默认状况,函数close()是当即返回的,而后TCP链接双方是经过

                FIN、ACK4分组来终止TCP链接的。固然,发送缓冲区还有数据的话,系统将试着将这些数据

                发送到对方。

           B、l_onoff非0,l_linger设置0,函数close()当即返回,并发送RST终止链接,发送缓冲区的数据丢弃。

           C、l_onoff非0,l_linger非0,函数close()不当即返回,而是在(a)发送缓冲区数据发送完并获得确认

                 (b)l_linger延迟时间到,l_linger时间单位为微妙。二者之一成立时返回。若是在发送缓冲区数据发送

                完并被确认前延迟时间到的话,close返回EWOULDBLOCK(或EAGAIN)错误。

3、客户端TCP链接“正常”关闭,服务器的几种状况:

          情形 客户端l_onoff设置为0, 
“正常”关闭
客户端l_onoff非0,l_linger设置0,“正常”关闭
服务器阻塞模式send,正阻塞在send函数未返回 客户端TCP发送FIN,服务器send函数返回成功(返回字节数是实际拷贝到发送缓冲区的字节数)。客户端发送RST。若是服务器再次调用send,将返回errno[32]:Broken pipe 客户端TCP发送RST,服务器函数返回成功(返回字节数是实际拷贝到发送缓冲区的字节 数)。若服务器再次调用send,则返回-1,errno[104]:Connection reset by peer。若再次调用send,则返回-1,errno[32]:Broken pipe
服务器空闲 客户端TCP发送FIN,若服务器没理会而调用send,客户端发送RST,send返回-1,errno[32]:Broken pipe 客户端TCP发送RST,若服务器没理会而调用send,send返回-1,errno[104]:Connection reset by peer。若再次调用send,则返回-1,errno[32]:Broken pipe

 

总之,一、收到对端RST后,仍然调入send(),则返回Connection reset by peer,再次调用send(),则返回Broken pipe

         二、收到对端FIN后,仍然调研哪一个send(),直接返回Broken pipe

相关文章
相关标签/搜索