从.NET传递套接字到非托管C++代码

6

我现在有一个.NET程序连接到服务器。有时我需要调用特殊的非托管C++代码,它使用与服务器的连接。

如何将套接字连接从.NET传递并在非托管C++代码中使用?

谢谢!


我认为这个功能不是开箱即用的。唯一能想到的是,如果C++应用程序启动了该进程,它将能够读取.NET应用程序的内存,但这是高级领域。 - NKCSS
可能还有其他的方法。你能否提供一个委托/函数指针给非托管代码,然后在 .Net 代码中将数据发送到套接字? - Nick
2个回答

8
Socket类有Handle属性,可以使用。 Socket.Handle @ MSDN 起初我对此持怀疑态度,但是轻松愉快地实现了它。
首先,我创建了一个非托管的C++动态链接库,导出一个可以处理socket的单一函数。这是我创建的函数。
#include <WinSock.h>

// This is an example of an exported function.
extern "C" __declspec(dllexport) void __stdcall DoStuffWithSocket(DWORD sock)
{
  const char *data = "woot\r\n";
  send((SOCKET)sock, data, strlen(data), 0);
}

该项目输出一个名为UnmanagedSocketHandler.dll的动态链接库,这个库在下一段代码中的P/Invoke签名中被提到。
以下是一个快速而简单的C#控制台应用程序,以调用该函数作为服务器。
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;

namespace SocketHandleShareTest
{
    class Program
    {
        static void Main(string[] args)
        {
            IPEndPoint ep = new IPEndPoint(IPAddress.Any, 5353);
            Socket sListen = new Socket(AddressFamily.InterNetwork, 
                                        SocketType.Stream, ProtocolType.Tcp);
            sListen.Bind(ep);
            sListen.Listen(10);
            Socket sClient = sListen.Accept();
            Console.WriteLine("DoStuffWithSocket() enter");
            Console.ReadLine();
            DoStuffWithSocket(sClient.Handle);
            Console.WriteLine("DoStuffWithSocket() exit");
            Console.ReadLine();
            sClient.Close();
            sListen.Close();
            Console.WriteLine("Done.");
            Console.ReadLine();
        }

        [DllImport("UnmanagedSocketHandler.dll")]
        static extern void DoStuffWithSocket(IntPtr sock);
    }
}    

最后,一个快速而简单的C#客户端应用程序与服务器通信。我无法找到任何关于为什么它有效的文档,但它确实有效。我建议你小心使用套接字。
using System.Net;
using System.Net.Sockets;

namespace SocketHandleShareTestClient
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] buf = new byte[40];
            Socket s = new Socket(AddressFamily.InterNetwork,
                                  SocketType.Stream, ProtocolType.IP);
            s.Connect("localhost", 5353);
            int len = s.Receive(buf);
            Console.WriteLine("{0} bytes read.", len);
            if (len > 0)
            {
                string data = Encoding.ASCII.GetString(buf, 0, len);
                Console.WriteLine(data);
            }
            s.Close();
            Console.ReadLine();
        }
    }
}

1
我没想到这是可能的...非常酷,测试工作做得很好。+1 - NKCSS

2

Socket 是指 System::Net::Sockets::Socket 吗?如果是的话,将 Socket::Handle 传递给非托管代码。


请注意,当 Socket 类被处理时,套接字将被销毁。 - jgauffin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接