2009-04-19 123 views
4

我想将message.WParam转换为Socket。如何将IntPtr/Int转换为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(袜子)转换为套接字,以便我可以调用Receive()?

回答

6

你不能这样做,因为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); 
    } 
    } 
} 
1

Socket class没有什么能做到这一点 - 尽管它使用底层句柄,但没有API来操纵它,而Handle property是只读的。

你可能是最好的P /调用recv并直接用你的IntPtr句柄调用它。

一个快速浏览的Rotor code的样子,你可以逃脱创建一个Socket,closing it's handle,然后设置它的m_handle场你自己。但是这需要Reflection,并且如果你的套接字已经连接(它听起来像是这样 - 因为你只是询问关于调用recv),那么你还必须操作Socket的私有状态 - 这使得这个想法更不可取,更脆弱。

+0

在其他语言(C++/Delphi的)这个插座declarated为整数。我认为WParam.ToUint32()会工作,但在C#中Socket不是int。为什么? – 2009-04-19 14:07:05