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

Tro*_*var 6 .net c# c++ sockets marshalling

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

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

提前致谢!

mek*_*ian 8

Socket类具有Handle属性,它可以被使用.

Socket.Handle @ MSDN

我对这是否会起作用持怀疑态度,但我能够毫不费力地让它工作.

首先,我创建了一个非托管C++ DLL来导出一个可以用套接字执行某些操作的函数.这是我创建的功能.

#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);
}
Run Code Online (Sandbox Code Playgroud)

该项目输出一个名为dll的dll 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);
    }
}    
Run Code Online (Sandbox Code Playgroud)

最后,一个快速而又脏的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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)