2011-04-13 11 views
5

Actualmente tengo un programa .NET que inicia una conexión a un servidor. A veces necesito llamar a un código C++ especial no administrado, que utiliza la conexión al servidor.Pase el socket de .NET al código de C++ no administrado

Cómo pasar y usar la conexión de socket de .NET en código C++ no administrado?

¡Gracias de antemano!

+0

No creo que esto sea compatible con la caja. Lo único que puedo imaginar es que si la aplicación C++ inició el proceso, podría leer la memoria de la aplicación .NET, pero eso es terretory avanzado. – NKCSS

+0

Puede haber otras formas de hacerlo. ¿Podría proporcionar un puntero delegado/función al código no administrado que luego envía datos al socket en el código .Net? – Nick

+0

Entonces, Nick, ¿cómo hacer esto? – Trogvar

Respuesta

7

La clase Socket tiene la propiedad Handle, que podría utilizarse.

Socket.Handle @ MSDN

yo era escéptico acerca de si esto iba a funcionar, pero yo era capaz de conseguir que funcione sin ningún problema en absoluto.

Para empezar, hice un dll C++ no administrado para exportar una sola función que puede hacer algo con un socket. Aquí está la función que creé.

#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); 
} 

El proyecto da salida a un archivo DLL llamado UnmanagedSocketHandler.dll, que es la biblioteca mencionada en el P/Invoke firma en el siguiente fragmento.

Aquí hay una aplicación de consola C# rápida y sucia para llamar a esa función como un Servidor.

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); 
    } 
}  

Última, una aplicación de cliente C# rápida y sucia para hablar con el servidor. No pude encontrar ninguna documentación sobre por qué funciona esto, pero funciona. Sería cauteloso sobre lo que intentas hacer con el zócalo.

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

No pensé que esto fuera posible ... un trabajo genial y bueno para probar esto. +1 – NKCSS

2

Socket significado System::Net::Sockets::Socket? Si es así, pase Socket::Handle al código no administrado.

+0

Tenga en cuenta que el socket se destruirá cuando se elimine la clase Socket. – jgauffin

+0

Derecha o finalizada. Uno puede esperar que la función no administrada sea sincrónica ... – ildjarn

Cuestiones relacionadas