2009-04-19 3 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; 
    } 
} 

Receive()を呼び出すためにIntrPtr(ソケット)をソケットに変換する方法はありますか?

答えて

6

Socketクラスが独自のプライベートソケットハンドルを作成して管理するため、実行できません。理論的には、あなたのソケットハンドルをSocketのプライベートフィールドに入れ替えるためにいくつかの邪悪な反射を使うことができますが、それはトータルのハックです。私はそれをやりません。ソケットは、整数としてdeclaratedされ、他の言語(C++ /デルファイ)で

[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/Invoking recvでIntPtrハンドルで直接呼び出すのが最も良いでしょう。 Rotor code

迅速ブラウズを使用すると、ソケットの作成を離れて得ることができるように、見えclosing it's handle、その後、それはあなた自身にm_handleフィールドの設定します。しかし、これにはReflectionが必要です。ソケットがすでに接続されている場合(それはrecvの呼び出しについて尋ねられているので)、Socketの私的な状態を操作する必要があります。より壊れやすい

+0

有効なソケットハンドルを考えると、あなたはこのように、P /呼び出しを経由してのWin32 recv関数を呼び出してデータを受信することができます。 WParam.ToUint32()はうまくいくと思いましたが、ソケットはC#でintではありません。なぜですか? –

+0

Socketは自身の状態を管理するクラスであるため、ハンドル(int)をカプセル化します。 –

関連する問題