如何释放多个进程之间共享的套接字描述符?

时间:2018-10-25 09:00:08

标签: c# linux sockets handle

背景

在Linux或BSD上,可以使用SCM_RIGHTS发送句柄以在不相关的进程之间打开文件或套接字,而我正在这样做,以便进程在侦听连接,然后将其转发给执行通信的过程。

问题

我不知道如何在不关闭套接字的情况下将套接字句柄从侦听过程中释放出来。

man close(3)中有两个相互矛盾的描述:

  

当与打开的文件描述关联的所有文件描述符都已关闭时,应释放打开的文件描述。

  

如果 fildes 引用套接字,则close()将导致该套接字被破坏。

我最初认为这意味着调用close()只会减少具有套接字的内核对象的引用计数,因此man close(3)中的最后一个描述意味着“当最后一个描述符为关闭”。

编辑:这是它的工作方式以及工作方式。

但是,当我运行测试时,似乎在侦听过程中在套接字描述符上调用close()时,它将立即关闭套接字,发送RST或{{1 }},具体取决于当时其他进程正在处理套接字。

一种解决方案是在处理过程中使用“您现在可以关闭套接字nnn”进行回调,但这将使许多套接字描述符在侦听过程中保持打开状态,并增加一些开销。

我知道我可以通过直接从任一进程中调用FIN来强制套接字启动关闭进程,但是我想防止

我认为存在一个简单的解决方案,但我找不到它。

问题

是否有一种方法可以从侦听进程中注销套接字描述符,以使其不再位于进程的文件描述符表中,而是激活套接字关闭功能?

源代码

用于发送套接字的shutdown()实现在这里(SCM_RIGHTSsend_fds):

发送套接字然后关闭它的代码在这里:

如果我注释掉第497行,则一切正常,但显然会出现大文件描述符泄漏。

native_close的接收端在这里:

1 个答案:

答案 0 :(得分:0)

tl; dr:关闭最后一个引用后,套接字将关闭。

我的问题的答案很可能是:

  

否,没有办法防止套接字关闭,但是因为套接字要等到最后一个描述符关闭后才会关闭,所以不需要。

安德鲁的答案是正确的,这使我步入正轨:毫无意义,其他人一直都这样做。

最后,问题是处理程序进程中的超时导致套接字关闭,但这使它看起来像是来自侦听器的close()调用。

当我停止监听过程中的close()呼叫时,它开始工作。发生这种情况是因为超时之后正确地关闭了句柄,但是仍然有一个引用(在侦听过程中),因此套接字保持打开状态。