簡體   English   中英

如何將IntPtr / Int轉換為Socket?

[英]How to convert IntPtr/Int to Socket?

我想將message.WParam轉換為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;
    }
}

如何將IntrPtr(sock)轉換為Socket,以便我可以調用Receive()?

你不能這樣做,因為Socket類創建並管理自己的私有套接字句柄。 從理論上講,你可以使用一些邪惡的反射來將你的套接字句柄裝入一個Socket的私有字段,但這是一個徹頭徹尾的黑客,我不會這樣做。

給定一個有效的套接字句柄,您可以通過P / Invoke調用Win32 recv函數來接收數據,如下所示:

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

Socket類中沒有任何東西可以做到這一點 - 雖然它使用底層句柄,但沒有API可以操作它,而Handle屬性是只讀的。

你可能最好只用P / Invoking recv並直接使用你的IntPtr句柄調用它。

快速瀏覽Rotor代碼看起來就像你可以創建一個Socket, 關閉它的句柄 ,然后將它的m_handle字段設置為你自己的。 但這需要反射,並且如果你的套接字已經連接(它聽起來像是 - 因為你剛剛詢問調用recv)那么你還必須操縱Socket的私有狀態 - 這使得這個想法更不可取和更脆弱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM