在今天的工作中,同事用netstat -anp 去查看一个进程的网络连接状态,发现有一个TCP连接send-Q显示37,TCP状态为CLOSE_WAIT状态。
在网上找到TCP状态机的迁移图如下
通过上图可以得到的是:TCP的一端接收到FIN,发出对FIN的ACK后,进入CLOSE_WAIT状态。发出FIN后就迁移到LAST_ACK状态。LAST_ACK状态下接收到对端FIN的ACK后,TCP连接关闭。
同事比较纠结图解说明是服务器那样迁移,我们这边看到是客户端连接处于CLOSE_WAIT状态。
如果收到FIN不适用TCP客户端的迁移的话,客户端TCP就无法被动关闭。对于没有保活机制的TCP是不合理的,所以应该是适用于TCP连接客户端的。
那么从而就可以看出,客户端read返回为0后,程序没有close对应的fd。
ls -l /proc/`pidof 进程名`/fd 查看各个fd对应系统的一个数字(如描述符6对应的1017)
netstat -anp | grep 进程名 获得CLOSE_WAIT的TCP连接,将源端口换算成16进制
cat /proc/net/tcp | grep 端口(16进制) 获得对应的socket描述符系统(1017)表示
ls -l /proc/`pidof 进程名`/fd | grep 1017,发现确实这个fd在这个进程中存在。
那么可以断定的是进程在探知到TCP连接关闭后,没有close这个fd。
接下来就是阅读代码,检查read是否对返回值为0的情况作了处理。
这里提到一个就是:如果删除一个日志文件,这个日志文件的fd被一个进程持有,可以用cat fd > bak.log进行恢复。
阅读(4692) | 评论(0) | 转发(0) |