Search code examples
c#socketswinsockintptr

How to convert IntPtr/Int to Socket?


I want to convert message.WParam to Socket.

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == Values.MESSAGE_ASYNC)
        {

            switch (m.LParam.ToInt32())
            {
                case Values.FD_READ:
                    WS2.Receive(m.WParam);
                case Values.FD_WRITE: break;
                default: break;
            }

        }
        else
        {
            base.WndProc(ref m);
        }
    }

public class WS2
{
    public static void Receive(IntPtr sock)
    {
        Socket socket = sock;
    }
}

How to convert the IntrPtr(sock) to Socket so I can call Receive()?


Solution

  • You can't do it because the Socket class creates and manages its own private socket handle. In theory you could use some evil reflection to jamb your socket handle into a private field of a Socket but that's a total hack and I wouldn't do it.

    Given a valid socket handle, you can receive data by calling the Win32 recv function via P/Invoke, like this:

    [DllImport("ws2_32.dll")]
    extern static int recv([In] IntPtr socketHandle, [In] IntPtr buffer,
      [In] int count, [In] SocketFlags socketFlags);
    
    /// <summary>
    /// Receives data from a socket.
    /// </summary>
    /// <param name="socketHandle">The socket handle.</param>
    /// <param name="buffer">The buffer to receive.</param>
    /// <param name="offset">The offset within the buffer.</param>
    /// <param name="size">The number of bytes to receive.</param>
    /// <param name="socketFlags">The socket flags.</param>
    /// <exception cref="ArgumentException">If <paramref name="socketHandle"/>
    /// is zero.</exception>
    /// <exception cref="ArgumentNullException">If <paramref name="buffer"/>
    /// is null.</exception>
    /// <exception cref="ArgumentOutOfRangeException">If the 
    /// <paramref name="offset"/> and <paramref name="size"/> specify a range
    /// outside the given buffer.</exception>
    public static int Receive(IntPtr socketHandle, byte[] buffer, int offset,
      int size, SocketFlags socketFlags)
    {
      if (socketHandle == IntPtr.Zero)
        throw new ArgumentException("socket");
      if (buffer == null)
        throw new ArgumentNullException("buffer");
      if (offset < 0 || offset >= buffer.Length)
        throw new ArgumentOutOfRangeException("offset");
      if (size < 0 || offset + size > buffer.Length)
        throw new ArgumentOutOfRangeException("size");
    
      unsafe
      {
        fixed (byte* pData = buffer)
        {
          return Recv(socketHandle, new IntPtr(pData + offset),
            size, socketFlags);
        }
      }
    }