将套接字句柄从 .NET 传递给非托管子进程
我当前有一个 .NET 程序启动与服务器的连接并启动另一个非托管可执行文件。本机进程应该接管相同的套接字(在子进程终止之前不要关闭连接至关重要!)并开始通过它与服务器进行通信。
上述程序都在 Windows 上运行,但我更喜欢不涉及 .NET 部分的 P/Invoke 的解决方案。顺便说一句,从父进程到子进程的通信不是问题,因此我可以轻松地在两者之间共享数据。
此外,一旦我开始使用本机进程中的套接字,我就不再需要从 .NET 进程中使用它,并且 .NET 进程将在我使用完本地进程中的套接字之前终止。非托管进程,因此除了解决方案之外,我还需要知道如何处理 .NET 中的 Socket 对象,以便其处理不会影响操作系统套接字及其可用性。
提前致谢!
I currently have a .NET program initiating a connection to a server and starting another, unmanaged executable. The native process should take over the same socket (it is essential for the connection not to be closed until the termination of the child process!) and start communicating through it with the server.
The aforementioned programs run both on Windows, however I'd prefer a solution that does not involve P/Invoke for the .NET part. As a side note, communication from parent to child process is not an issue so I can easily share data between the two.
Furthermore, once I start using the socket from the native process I don't need to use it from the .NET process anymore and the .NET process will terminate before I'm done using the socket from the unmanaged process, thus along with the solution I need to know what to do with the Socket object in .NET so that its disposal doesn't affect the OS socket and its usability.
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
.NET 2.0 及更高版本提供了方便的方法 DuplicateAndClose。
更新: 看起来需要进行黑客攻击才能找出目标套接字存储在 SocketInformation.ProtocolInformation 中的位置(偏移量)。这可以通过捕获源进程中的字节数组,然后在另一个 .NET 进程中重新创建套接字并在那里获取套接字句柄(在第二个进程中)来完成。然后查看数据在字节数组中的位置。
还有一种很好的非托管方法来复制套接字,此处描述。
.NET 2.0 and later offers handy method DuplicateAndClose.
Upd: looks like a hack will be needed to find out where (at which offset) in SocketInformation.ProtocolInformation the destination socket is stored. This can be done by capturing the byte array in the source process, then re-creating a socket in another .NET process and getting the socket handle there (in that second process). Then look where the data is in the byte array.
Also there's a good unmanaged way to duplicate sockets, described here.
我认为 .NET Socket 类创建的套接字句柄默认是可继承的。 IIRC 如果您使用 Process.Start 和 ProcessStartInfo.UseShellExecute = false 生成子进程(ShellExecute 不允许句柄继承),则您的子进程应该已经继承了套接字句柄。您是否尝试简单地将 Socket.Handle 传递给子进程并在那里使用它?我认为只要子进程拥有继承的句柄,套接字就会保持打开状态,即使在创建它的进程消失之后也是如此。 (我从未直接使用过它,但我曾经遇到过由这种行为导致的严重错误。)但是,套接字可能已使用 FILE_FLAG_OVERLAPPED 等标志打开,并且您必须使用正确的函数组合来访问它。
I think socket handles created by the .NET Socket class are inheritable by default. IIRC If you spawn the child process using
Process.Start
andProcessStartInfo.UseShellExecute = false
(ShellExecute doesn't allow handle inheritance), your child process should already inherit the socket handle. Did you try simply passing the Socket.Handle to the child process and using it there? And I think that as long as the child process owns the inherited handle, the socket remains open, even after the process that created it is gone. (I never used this directly, but I once had a mean bug that resulted from this behavior.) However, the socket might have been opened with flags like FILE_FLAG_OVERLAPPED etc. and you'll have to use the right combination of functions access it.