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

C# 如何释放多个进程之间共享的套接字描述符?,c#,linux,sockets,handle,C#,Linux,Sockets,Handle,背景 在Linux或BSD上,可以通过SCM_RIGHTS在不相关的进程之间发送打开文件或套接字的句柄,我已经完成了这项工作,因此On process正在侦听连接,然后将句柄转发给执行通信的进程 问题 我不知道如何在不关闭套接字的情况下将套接字句柄从侦听进程中释放出来 man close(3)中有两个相互冲突的描述: 当与打开的文件描述关联的所有文件描述符都已关闭时,打开的文件描述应被释放 及 如果fildes指的是插座,close()将导致插座损坏 我最初认为这意味着调用close()只会减少

背景

在Linux或BSD上,可以通过
SCM_RIGHTS
在不相关的进程之间发送打开文件或套接字的句柄,我已经完成了这项工作,因此On process正在侦听连接,然后将句柄转发给执行通信的进程

问题

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

man close(3)
中有两个相互冲突的描述:

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

如果fildes指的是插座,close()将导致插座损坏

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

编辑:这就是它的工作原理,也是它的工作原理

但是,当我运行测试时,似乎只要我在侦听过程中对套接字描述符调用
close()
,它就会开始关闭套接字,发送
RST
FIN
,具体取决于另一个进程当时对套接字所做的操作

一种解决方案是在处理过程中使用“youcanowclosesocketnnn”进行回调,但这会在侦听过程中保持许多套接字描述符处于打开状态,并增加一些开销

我知道我可以通过直接从任一进程调用
shutdown()
来强制套接字启动关闭进程,但我想阻止它

我假设存在一个简单的解决方案,但我找不到

问题

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

源代码

用于发送套接字的
SCM\u权限
实现在这里(
send\u fds
native\u close
):

发送套接字然后将其关闭的代码如下:

如果我把第497行注释掉,一切正常,但显然会有一个大文件描述符泄漏

SCM\u权限的接收端在这里:


    • tl;dr:当最后一个引用关闭时,套接字关闭

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

      不,没有办法阻止套接字关闭,但是不需要关闭,因为套接字在最后一个描述符关闭之前不会关闭

      安德鲁的回答是正确的,这让我走上了正轨:这毫无意义,其他人总是这么做

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


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

      发布代码。这似乎很奇怪,因为像
      inetd
      这样的服务使用
      accept()
      来创建传入套接字连接,
      fork()
      这样子进程就可以处理连接,然后
      close()
      在子进程继续使用套接字的同时在父进程中接受套接字。有关BSD示例,请参阅。添加了指向OP的源代码链接