当父进程被终止时,关闭一个一直等待子进程的套接字

当父进程被终止时,关闭一个一直等待子进程的套接字

情况如下:

  • 服务/父进程连接到“公共端口”(父进程是服务)。该“公共端口”为 11000。当新请求从端口 11000 到达父进程时,服务器会使用“私有”端口(套接字)将该请求发送到子进程。您知道,这是实现服务器的典型方式。

  • 父进程被杀死但是套接字没有关闭(我还不知道原因)。

  • 孤立进程正在等待套接字关闭,并且 pkill 不起作用(它处于不间断睡眠状态)。

  • 我无法再次运行服务器,因为服务器说地址(0.0.0.0:11000)已被使用。

因此,我有两个选择,关闭“内部套接字”以完成孤立进程,或者以某种方式“释放”地址/端口 0.0.0.0:11000 以再次运行服务器,并使孤立进程处于等待状态。这样做是为了避免每次服务器失败时都重新启动服务器,同时我调查问题。

有关该情况的有用信息(子进程的 pid 是 1993):

$ sudo lsof -np 1993

[...]
proc 1993 root 16u  IPv4  14997  0t0  TCP 127.0.0.1:42982->127.0.0.1:37528 (CLOSE_WAIT)

因此,我想要关闭的端口是 37528。相应套接字的文件描述符是 16u(或者我是这么认为的)。

$ sudo strace -p 1993

Process 1993 attached
futex(0x2fff414, FUTEX_WAIT_PRIVATE, 1, NULL

$ netstat -np
[...]
tcp      0   0 127.0.0.1:42982     127.0.0.1:37528    CLOSE_WAIT  -  

如果我尝试通过以下方式连接到孤立进程gdb

$ gdb -p 1993
Attaching to process 1993
{process_path} (deleted): No such file or directory.

我认为这是因为它的父进程被杀死了。问题是,我无法连接到孤儿进程来调用close(16u)

我怎样才能“解决”这种情况?

笔记:我已经尝试重新启动networking服务,但不起作用。这是 Ubuntu Server 14.04(VirtualBox),我使用 ssh 连接到我的机器。没有网络管理器。

我已尝试将应用ifdownifup每个接口(eth0、eth1、lo 和 virbr),但它们不会关闭套接字。

答案1

没有简单的方法。首先,这与联网关闭等待你的子进程在回复数据包确认, 和关闭套接字并向其对等端发送数据包。在关闭等待说明该过程正在完成某项操作,最后它将调用关闭(),促使内核发出FIN数据包。

换句话说,在关闭等待表明该进程正在尝试完成某项操作,不是等待对方的回复;因此关闭网络、重新启动接口等都无济于事。

总的来说,这不应该本身一个大问题:有些进程挂起并没有什么错关闭等待状态。让您感到困扰的是难以理解:您声明父进程侦听端口 11000,然后在端口 37528 上联系子进程,但您声明,在父进程死亡后,您无法启动服务器的新实例,因为端口 11000 未释放。但您刚才声明不是子进程在使用它!那么是谁在使用它?

无论如何,您可以尝试一些事情;

  1. 您是否尝试过使用-9选项?这是你能想出的最强的办法。

  2. 您可以使用斯特拉斯从一开始就跟踪子进程中的系统调用(或者是子进程?),通过

    strace -f YourParentProcess
    

    这也将遵循*fork()*ed 进程。

  3. 我猜你很可能忘记这个孩子,并试图确定为什么端口 11000 似乎被占用,以及被谁占用。你应该尝试更方便的命令

    ss -lntp | grep 11000
    

    调查此事。

相关内容