C# 在Linux上从.NET内核手动调用recvmsg不会';不归

C# 在Linux上从.NET内核手动调用recvmsg不会';不归,c#,linux,sockets,.net-core,C#,Linux,Sockets,.net Core,我正在为.NETCore编写一个DBus客户端。对于某些功能(例如systemd的抑制器锁),需要通过Unix套接字连接接收文件描述符,这些功能需要recvmsg放入struct msghdr中的控件相关消息。NETs套接字API不允许我访问该函数(或抽象),所以我必须手动调用它 导致我第一次调用recvmsg的代码的核心是。当我在net462上编译它,并在我的Ubuntu16.04版或Yocto发行版(也使用Mono)上通过Mono 5.0.1运行它时,一切都按预期运行 当我根据netcore

我正在为.NETCore编写一个DBus客户端。对于某些功能(例如systemd的抑制器锁),需要通过Unix套接字连接接收文件描述符,这些功能需要
recvmsg
放入
struct msghdr
中的控件相关消息。NETs套接字API不允许我访问该函数(或抽象),所以我必须手动调用它

导致我第一次调用recvmsg的代码的核心是。当我在net462上编译它,并在我的Ubuntu16.04版或Yocto发行版(也使用Mono)上通过Mono 5.0.1运行它时,一切都按预期运行

当我根据netcoreapp1.1/netstandard1.6编译它并使用
dotnet
运行它时,问题就开始了:针对
org.freedesktop.DBus
recvmsg
调用在第一次
Hello
调用时不会返回

我可以通过
dbus monitor--system
看到方法调用已经离开了我的应用程序,dbus发送了方法返回以及
NameOwnerChanged
nameaccessed
信号

几点注意:

  • 对于我在Ubuntu上的测试,我已经将
    iovec
    msghdr
    中的
    size\t
    字段从
    int
    更改为
    long
    ,实际上是64位的(尽管它看起来像是结构所需的对齐方式使得它仍然可以工作)
  • 套接字上的实际
    ConnectAsync
    调用略有不同:对于net462,我从.NET Core 1.1复制了
  • 为了获得本机套接字句柄,我可以在net462上使用handle属性,但在netcoreapp1.1版本中
  • 我还检查了.NETCore2.0Preview2版本,它们的行为与.NETCore1.1完全相同
  • 在套接字上调用
    Read
    而不是
    recvmsg
    是可行的,尽管内部读取只会映射到
    recvmsg
  • 我比较了Mono和.NET Core在套接字上的公共属性,没有明显的区别:访问独占性使用在Mono上工作,但在.NET Core上抛出
  • 在接收线程开始工作之前,会有一些身份验证代码。这会从套接字执行一些基于TPL的读取
我尝试过浏览CoreFX套接字代码,但由于涉及的复杂性,这并不有趣


缺少的环节是什么?

连续出现了两个问题

首先,我的receive方法成功地吞并了一个异常,如果我运行了连接的Dispose方法,而不是从程序中按CTRL+C'ing,则该异常可能是可见的

System.TypeLoadException: Cannot marshal field 'control' of type 'msghdr': Unknown error.
   at System.StubHelpers.ValueClassMarshaler.ConvertToNative(IntPtr dst, IntPtr src, IntPtr pMT, CleanupWorkList& pCleanupWorkList)
   at Dbus.Connection.recvmsg(IntPtr sockfd, msghdr& buf, Int32 flags)
   at Dbus.Connection.receive()
因此,
recvmsg
从未实际调用过。原因是键入了
control
字段
int[]
。我将其更改为
int*
,并添加了另一个
fixed

不过,奇怪的是,Mono能够用
int[]
字段封送这个结构,而.NET核心却不能

在此之后,
recvmsg
实际上被调用,但立即返回-1。不过,如果我只是使用.NET套接字
阅读
,一切都很好。我选择通过libcapi直接运行整个套接字处理,不再使用.NET核心套接字类型。现在,
recvmsg
按预期工作。我假设我基于TPL的DBus授权离开套接字时有一个活动读取,我的receive方法正在执行第二个“阻塞”的读取,但我还没有验证这个假设