我试图在linux内核中找到在进程死后进行清理的位置。具体地说,我想看看在使用-9信号终止进程之后,它是否/如何处理打开的TCP连接。我非常确定它会关闭所有连接,但我想查看详细信息,以及是否有任何连接没有正确关闭的可能性。
欢迎指向linux内核源代码的指针。
发布于 2010-12-15 11:28:01
进程终止的核心部分由exit.c:do_exit()处理。此函数调用exit_files(),后者又调用put_files_struct(),后者又调用close_files()。
close_files()遍历进程打开的所有文件描述符(包括所有套接字),在每个描述符上调用filp_close(),后者在struct file对象上调用fput()。当放置了对struct file的最后一个引用时,fput()调用文件对象的.release()方法,对于套接字,该方法是net/socket.c中的sock_close()函数。
发布于 2010-12-15 01:28:57
我非常确定套接字清理更多的是在进程死后释放所有文件描述符的副作用,而不是由进程清理直接完成的。
不过,我要冒险一试,假设您遇到了网络编程的一个常见陷阱。如果我猜对了,您的问题是在进程被终止后试图绑定到一个地址时得到一个"Address in use“错误(EADDRINUSE),那么您正在运行套接字的TIME_WAIT。
如果是这种情况,您可以等待超时,通常是60秒,也可以修改套接字以允许立即重用,如下所示。
int sock, ret, on;
struct sockaddr_in servaddr;
sock = socket( AF_INET, SOCK_STREAM, 0 ):
/* Enable address reuse */
on = 1;
ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );编辑
从您的评论来看,您似乎遇到了半开放连接的问题,并且没有完全理解TCP的工作原理。TCP无法知道客户端是死机还是空闲。如果对客户端进程执行kill -9操作,则四次关闭握手永远不会完成。这不应该在您的服务器上留下打开的连接,所以您可能仍然需要获取一个网络转储来确定发生了什么。
在不确切知道自己在做什么的情况下,我不能肯定地说你应该如何处理这个问题,但你可以阅读关于TCP Keepalive here的文章。其他几种选择是定期向客户端发送空或空消息(可能需要修改您的协议),或者在空闲连接上设置硬计时器(可能会导致丢失有效连接)。
https://stackoverflow.com/questions/4438146
复制相似问题