I want to convert message.WParam 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;
}
}
How to convert the IntrPtr(sock) to Socket so I can call Receive()?
如何将IntrPtr(sock)转换为Socket,以便我可以调用Receive()?
2 个解决方案
#1
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.
你不能这样做,因为Socket类创建并管理自己的私有套接字句柄。从理论上讲,你可以使用一些邪恶的反射来将你的套接字句柄装入一个Socket的私有字段,但这是一个彻头彻尾的黑客,我不会这样做。
Given a valid socket handle, you can receive data by calling the Win32 recv function via P/Invoke, like this:
给定一个有效的套接字句柄,您可以通过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);
}
}
}
#2
There's nothing in the Socket class to do this - though it uses an underlying handle, there's no API to manipulate it and the Handle property is read-only.
Socket类中没有任何东西可以做到这一点 - 虽然它使用底层句柄,但没有API来操作它,而Handle属性是只读的。
You would probably be best off by just P/Invoking recv and calling it directly with your IntPtr handle.
你可能最好只用P / Invoking recv并直接使用你的IntPtr句柄调用它。
A quick browse of the Rotor code looks like you could get away with creating a Socket, closing it's handle, and then setting it's m_handle field to your own. But that requires Reflection, and if your socket is already connected (which it sounds like it is - since you just asked about calling recv) then you'd also have to manipulate the private state of Socket - which makes this idea even less palatable and more fragile.
快速浏览Rotor代码看起来就像你可以创建一个Socket,关闭它的句柄,然后将它的m_handle字段设置为你自己的。但这需要反射,并且如果你的套接字已经连接(它听起来像是 - 因为你刚刚询问调用recv)那么你还必须操纵Socket的私有状态 - 这使得这个想法更不可取和更脆弱。
#1
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.
你不能这样做,因为Socket类创建并管理自己的私有套接字句柄。从理论上讲,你可以使用一些邪恶的反射来将你的套接字句柄装入一个Socket的私有字段,但这是一个彻头彻尾的黑客,我不会这样做。
Given a valid socket handle, you can receive data by calling the Win32 recv function via P/Invoke, like this:
给定一个有效的套接字句柄,您可以通过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);
}
}
}
#2
There's nothing in the Socket class to do this - though it uses an underlying handle, there's no API to manipulate it and the Handle property is read-only.
Socket类中没有任何东西可以做到这一点 - 虽然它使用底层句柄,但没有API来操作它,而Handle属性是只读的。
You would probably be best off by just P/Invoking recv and calling it directly with your IntPtr handle.
你可能最好只用P / Invoking recv并直接使用你的IntPtr句柄调用它。
A quick browse of the Rotor code looks like you could get away with creating a Socket, closing it's handle, and then setting it's m_handle field to your own. But that requires Reflection, and if your socket is already connected (which it sounds like it is - since you just asked about calling recv) then you'd also have to manipulate the private state of Socket - which makes this idea even less palatable and more fragile.
快速浏览Rotor代码看起来就像你可以创建一个Socket,关闭它的句柄,然后将它的m_handle字段设置为你自己的。但这需要反射,并且如果你的套接字已经连接(它听起来像是 - 因为你刚刚询问调用recv)那么你还必须操纵Socket的私有状态 - 这使得这个想法更不可取和更脆弱。