2016-12-07 52 views
0

数据包通过NetworkStreamTcpListener发送到TcpClient。数据包不是很大(5字节),但频率很高(大约每秒1000或更多)。你能给我建议,我应该如何处理它最有效?现在我使用async获取流,填充缓冲区,然后将其剪切到数据包。之后重复这个过程。但 在某些时候我失去了真正的序列。C#我应该如何更有效地使用NetworkStream?

s是NetworkStream。

分组具有2个字段:类型(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抽象是一个字节流。不能保证在每一个“发送”调用的一端都会匹配1-1,而在另一端调用“接收”。如果您想要“数据包”或“消息”,则需要在TCP上实现成帧逻辑,或移至更高级别的抽象。 –

+0

@Damien_The_Unbeliever 是的,谢谢!只读5字节,它变得好多了! – Krelembra

回答

0

设置MAXVALUEPACKET = 5到精确读取每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个字节。

相关问题