我有一个服务器进程和一个在同一台Linux机器上运行的客户端进程.
有时当我杀死-9客户端时,我看到tcpdump发送了FIN,ACK消息.当然死去的客户不可能做到这一点,因为他与SIGKILL残酷地死了.所以我猜Linux操作系统处理连接关闭.
有时我看不到任何连接 – 关闭处理,连接保持“ESTABLISHED”(由netstat).
我总是看到在Linux ubuntu 4.4.0-53-generic中关闭了一个连接.
有时我在Linux 3.13.11(纯内核,而不是Ubuntu)中看到连接被关闭.
我的问题是:
> Linux是否处理关闭连接?
1.1在SIGKILL?
1.2.当应用程序正常关闭,但不调用close()?
>此功能是否在内核版本3.13.11和4.4.0之间发生了变化? Ubuntu有什么用吗?
>如果这两个进程不在同一个Linux机器上会怎么样?它的行为是否相同?
>为什么连接有时会保持“ESTABLISHED”?
>我知道TCP keepalive套接字选项.如果Linux真的处理关闭连接.它们为什么存在?只有FIN,ACK数据包丢失?
解决方法:
一个广泛的问题.也许有人可以权衡你在特定内核版本之间的内核TCP堆栈的问题.
一般答案:
从客户端
>如果发生SIGKILL信号,内核将终止程序执行,并关闭进程的打开文件描述符.内核的TCP套接字处理方式与常规文件的处理方式略有不同,因为它们需要刷新并通过TCP shudown进程.
来自客户端的立即“FIN,ACK”和更长的套接字关闭的差异可能取决于客户端应用程序终止时客户端TCP连接的状态.但通常内核会关闭应用程序的开放套接字.
从服务器端
>服务器并不总是知道客户端何时断开连接.确定客户端是否挂断的最可靠方法是尝试从返回EOF的套接字读取.
TCP旨在抵御连接延迟和间歇性故障.这也转化为在FIN,ACK 4路断开握手未发生的情况下可靠地检测断开的一些挑战.
摘要
您可能在kill -9客户端上看到的是服务器进入TCP状态的CLOSE_WAIT,它正在等待TCP超时.这可能需要一段时间.即使客户端已经消失,如果内核没有处理TCP断开连接握手,服务器也必须超时.
如果我记得这可能需要几秒钟的时间,而且可能是因为在同一主机上同时运行客户端和服务器而仍然看到ESTABLISHED.
标签:linux,tcp,networking
来源: https://codeday.me/bug/20190813/1648524.html