2016-07-16 5 views
-1

これは、非同期ソケットを使用してデータを受信するための有効な(役に立たない)例です。 完全なコードはMSDNです。 BeginReceiveメソッド内C#バイト配列が影響を受けるthrou参照のないメソッド

public class Class1 
{ 
    private static void Receive(Socket client) 
    { 
     StateObject state = new StateObject(); 
     state.workSocket = client; 

     //state.buffer is a empty byte array 
     client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
      new AsyncCallback(ReceiveCallback), state); 
    } 

    private static void ReceiveCallback(IAsyncResult ar) 
    { 
     StateObject state = (StateObject) ar.AsyncState; 
     Socket client = state.workSocket; 

     int bytesRead = client.EndReceive(ar); 

     //state.buffer contains now all the received data. 
     state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead); 
    } 
} 

public class StateObject 
{ 
    public Socket workSocket = null; 
    public const int BufferSize = 256; 
    public byte[] buffer = new byte[BufferSize]; 
    public StringBuilder sb = new StringBuilder(); 
} 

何のrefまたはoutキーワードが存在しないためstate.bufferフィールドに影響を与えることは不可能である必要があります。

しかし、バイト配列は実際には変更された値を持っています。

state.bufferフィールドが空であり、Receiveメソッドではどのようにして、ReceiveCallbackメソッドでアクセスすると受信したすべてのデータが含まれるのでしょうか?あなたは時間がかかった場合、少なくともは、あなたが投稿MSDNリンク上コメントを読むために

+0

この場合、 'buffer'は配列です。配列参照自体は変更されていませんが、配列の* contents *は変更可能です。 – Eris

+0

[Passing By refとout]の重複している可能性があります(http://stackoverflow.com/questions/1644372/passing-by-ref-and-out) – Eris

+0

正しく動作する場合、どのように役に立たない例ですか? –

答えて

2

refが存在しないためstate.bufferフィールドに影響を与えることは不可能であるか、またはアウトすべきキーワード

いいえこれは真実ではありません。 state.bufferが指す実際のオブジェクトは別の方法で変更できますが、その参照は変更できません。ここ

簡単な例は次のとおり

static void Main() 
{ 
    byte[] arr = new byte[] { 1, 2, 3, 4, 5 }; 

    ChangeTheObject(arr); 

    foreach(byte b in arr) { 
     Console.WriteLine(b); 
    } 
} 

static void ChangeTheObject(byte[] arr) 
{ 
    arr[2] = 7; 
} 

Main()

1 
2 
7 
4 
5 

オブジェクト自体を印刷することを受信する方法で変更することができます。


ただし、参照自体を変更することはできません。

static void ChangeTheReference(byte[] arr) 
{ 
    arr = new byte[] { 6, 7, 8, 9, 10 }; 
} 

あなたは、新しいオブジェクトへのローカル参照を再割り当てしましたので、これはMain()の元の配列の内容は変更されません。あなたは元のオブジェクトを変更しませんでした。それはrefキーワードが便利な場所です。


例のメソッドは、参照ではなく配列の内容を変更しています。

0

、あなたは何が起こっているのかを理解するであろう:

は、リモートデバイスからのデータの受信を開始します。

client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
    new AsyncCallback(ReceiveCallback), state); 

リモートデバイスからデータを読み込みます。

int bytesRead = client.EndReceive(ar); 

次回は、すでに可能ですか何を主張する前に説明しているもの読んで理解するために多くの時間がかかります。

関連する問題