【发布时间】:2013-10-19 14:34:42
【问题描述】:
我有一个 SIP 服务器(守护进程),它正在侦听 tcp 套接字 5060。现在在这个父进程中,我创建了一个子进程并在子进程中做一些事情。 现在,当我在父进程中关闭此 tcp 套接字并尝试再次创建(假设我在此服务器上禁用和启用 SIP)时,会发生什么,创建此套接字会给我错误。我已经调试了这个问题并找到了根本原因。根本原因是在创建子节点时,它从父节点继承(获取副本)所有打开的 fd/套接字。当父级关闭 tcp 套接字时,它仍然在子级(ref_counter!=0)中打开,因此我无法在父级中再次打开套接字!
现在,我想要的通用解决方案是 - 一旦启动子进程,它就会检查任何打开的 fd(IPv4/TCP 类型)并关闭它们,这样子进程就不会对父进程产生副作用。这如何在 C-unix 中完成? 我已经考虑过按照 system(lsof | grep | awk) 的方向进行操作并获取文件描述符,但是我该如何关闭它们呢? 任何其他解决方案来关闭孩子的套接字?有没有一种方法可以传递端口号,它给了我已经创建的 fd ?
我不想要的解决方案是(这对我没有帮助)-
1.在父进程中,最初在创建带有一些标志的tcp套接字时,它们不会被子进程复制。 (我无法修改父级中的套接字创建)!
2. 在创建子进程时将文件描述符从父进程传递给子进程。我不能那样做,因为我没有那个 fd。解决方案必须是需要放在子进程中的东西!
谢谢
【问题讨论】:
-
如果不编辑父进程代码,我不确定这是否可行。每当我遇到这个问题时,我都会使用您不想要的解决方案 2。
-
一种可能的方法,如果使用 Linux:检查 /proc/
/fd/ 中的链接。关闭链接到 'socket:[inode]' 的描述符。 -
我怀疑您误诊了根本原因,现在正在寻找两种不受欢迎的解决方案来解决您自己制造的问题。孩子们首先关闭监听套接字,而父母在分叉后立即关闭数据套接字应该是微不足道的。
-
@MichaelBrennan - 谢谢。如果这些链接(它们只是我将使用 lsof 或 /proc/
/fd 的输出的 awk 解析的数字)可以直接传递给 close(int fd),我只是感到困惑。但是,我刚刚尝试过,它确实有效。 -
OP,无意冒犯,但是如果您使用 awk 解析 lsof 以关闭 C 程序中的套接字,那么您将直接偏离轨道。您需要考虑重新设计或给出一个非常有说服力的理由,说明这是必要的。