2016-12-07 12 views
0

TcpListenerからTcpClientへのデータパケットはNetworkStream経由で送信されます。パケットは大きくはありませんが(5バイト)、大きな頻度(毎秒約1000以上)があります。どのように私はそれを最も効果的に処理する必要がありますアドバイスを与えることができますか?今私はバッファを埋めるストリームを得るために非同期を使用し、パケットにカットします。その後、プロセスが繰り返されます。しかし、ある時点で は本当のシーケンスを失います。C#NetworkStreamをより効果的に使用するにはどうすればよいですか?

はNetworkStreamです。タイプ(1バイト(バイト))と値(4バイト(INT))

MAXVALUEPACKET = 4096

クライアントコード:

async Task process() 
    { 
     bool flag = false; 
     while (true) 
     { 
      byte[] actionBuffer; 
      flag = false; 
      actionBuffer = await ReadFromStreamAsync(); 
      while (!flag) 
      { 
       byte type = actionBuffer[0]; 
       int value = 0; 
       if (type > 0) 
       { 
        byte[] valueBytes = { actionBuffer[4], actionBuffer[3], actionBuffer[2], actionBuffer[1] }; 
        value = BitConverter.ToInt32(valueBytes, 0); 
        actionBuffer = actionBuffer.Skip(5).ToArray(); 
        CommonVariables.RawMessages.Add(new KeyValuePair<byte, int>(type, value)); 
        OnHandler(); 
       } 
       else 
        flag = true;      
      }  
     } 
    }   
    byte[] buf = new byte[MAXVALUEPACKET]; 
    async Task<byte[]> ReadFromStreamAsync() 
    { 
     await s.ReadAsync(buf, 0, MAXVALUEPACKET); 
     return buf; 
    } 
+0

['ReadAsync'](https://msdn.microsoft.com/en-us/library/hh137813(v = vs.110).aspx):" * TResult *パラメータの値には、結果の値は、現在利用可能なバイト数が要求された数よりも小さい場合に要求されたバイト数より小さくなる可能性があります。 " –

+0

そして最も重要なのは、TCP抽象化はバイトストリームです。一方の「Send」の各コールが他方の「Receive」のコールと1-1で一致するという保証はありません。 "Packets"や "Messages"が必要な場合は、TCPの上にフレーミングロジックを実装するか、より高いレベルの抽象化に移行するのは最大*あなた*です。 –

+0

@Damien_The_Unbeliever はい、ありがとう! 5バイトしか読み込めませんでした。 – Krelembra

答えて

0

MAXVALUEPACKET = 5に設定

パケットは、2つのフィールドを有しています正確に5バイトごとに読み取ると、バイトの損失を防ぐのに役立ちます。

 const int MAXVALUEPACKET = 5; 
     async Task process() 
     { 
      while (true) 
      { 
       var actionBuffer = await ReadFromStreamAsync(); 
       byte type = actionBuffer[0]; 
       int value = 0; 
       if (type > 0) 
       { 
        byte[] valueBytes = { actionBuffer[4], actionBuffer[3], actionBuffer[2], actionBuffer[1] }; 
        value = BitConverter.ToInt32(valueBytes, 0); 
        CommonVariables.RawMessages.Add(new KeyValuePair<byte, int>(type, value)); 
        OnHandler(); 
       } 
      } 
     } 

     async Task<byte[]> ReadFromStreamAsync() 
     { 
      await s.ReadAsync(buf, 0, MAXVALUEPACKET); 
      return buf; 
     } 

元のコードロジックの問題は、反復が820番目のループに達し、1バイトが残っていて、整数値を読み取るロジックに失敗することです。私は、サーバーが常にすべての部分に正確に5バイトを書き込むと仮定しています。

関連する問題