2016-09-13 22 views
0

これはSocketからデータを読み取る良い方法ですか?ソケット受信データの非同期/待機待ち

public class StateObject : IDisposable 
{ 
    private const int _bufferSize = 1024; 
    public byte[] Buffer { get; } = new byte[_bufferSize]; 
    public int BufferSize { get; } = _bufferSize; 
    public MemoryStream MsStream { get; } 

    public EnhStateObject() 
    { 
     MsStream = new MemoryStream(); 
    } 

    public void Dispose() 
    { 
     MsStream.Dispose(); 
    } 
} 

public async static Task<int> ReceiveAsync(this Socket client, StateObject state) 
{ 
    var task = await await Task<int>.Factory.FromAsync(
    (cb, s) => client.BeginReceive(state.Buffer, 0, state.BufferSize, SocketFlags.None, cb, s), 
    client.EndReceive, null).ContinueWith(t => 
    { 
     state.MsStream.Write(state.Buffer, 0, t.Result); 
     return t; 
    }); 

    if (task == state.BufferSize) await client.ReceiveAsync(state); 

    return task; 
} 

つまり、オブジェクトの外部に転送し、受信した情報を再帰呼び出しによって格納します。

同じFromAsyncラッパーを使用してこれを行うよりエレガントな方法がありますか?

+1

これが機能する場合は、SOよりもCode Reviewに適している可能性があります。どちらの方法でも詳細を追加する必要があるかもしれません(例えば 'StateObject'の定義が役に立ちそうです)。 'await await'は疑わしく見える。 –

+0

投稿を更新しました。 'StateObject'について何も特別なことはありません。 '[await await' [here](https://blogs.msdn.microsoft.com/pfxteam/2011/10/24/task-run-vs-task-factory-startnew/) –

+0

に同意すると簡単にできます:削除'Task .Factory.FromAsync'と' ContinueWith'' t.Result'から返ります。 –

答えて

1

いいえ、これはソケットからデータを読み取る良い方法ではありません。あなたはここに車輪を再発明しています。 use NetworkStream instead。なぜ低レベルのSocket APIを使用する必要があるのか​​わかりませんが、そうではありません。代わりに

、そうのように、呼び出し場所でNetworkStreamであなたのSocketをラップ:周りに渡すために何の状態オブジェクトを、あなた:

Socket socket = ....; 
Stream stream = new NetworkStream(socket); 

次に、あなたがちょうどあなたが(ボーナスポイントを期待するようReadAsync()を使用してデータを読み取ることはできませんテストでは、標準MemoryStreamで流れを模擬することができます)

var buffer = new byte[1024]; 
var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length); 

は、TCPを使用している場合、私はthe TcpClient APIを使用して代わりのソケットに直接働くお勧めします。

+0

Thnxs、それは '.net4.6.1'を使用している私のサーバサイドに適しています。 '.net4'のクライアントはどうですか?どのようにしてAPMを作成し、そこに 'Sockets' APIのレベルまで落ちないのですか? –

+0

あなたの質問には、使用している.NETフレームワークを含む要件を言及することをお勧めします。 .NET 4には 'ReadAsync'はありませんが、' NetworkStream'はあります。残念ながら、古い 'BeginRead' /' EndRead'メソッドを使用せずに、このバージョンのストリームで非同期読み込みを使用する方法はありません。 –

+0

残念ですが、将来私はそれをテイクします。 –

関連する問題