2017-08-29 49 views
0

我写了一个TCP监听器接收来自单个客户端的图像序列,这是服务器的代码:它接收帧很好使用读取int32时,长度标头突然出现错误值?

new Thread(() => 
{ 
    while (true) 
    { 
    displayingFrame.Start(); // another thread to display images 
    Socket socket = listener.AcceptSocket(); 
    TcpClient client = new TcpClient(); 
    client.Client = socket; 
    Debug.WriteLine("Connection accepted."); 

    var childSocketThread = new Thread(() => 
    { 
     NetworkStream ns = client.GetStream(); 
     BinaryReader br = new BinaryReader(ns); 

     while (true) 
     { 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      int length = br.ReadInt32(); 

      Debug.WriteLine("length : " + length); 

      byte[] buf = new byte[1024]; 
      int totalReaded = 0; 
      int readed = 0; 
      while (totalReaded < length) 
      { 
       readed = br.Read(buf, 0, buf.Length); 
       ms.Write(buf, 0, readed); 
       totalReaded += readed; 
      } 

      byte[] frame = ms.ToArray(); 
      this.frames.Enqueue(frame); 
      Debug.WriteLine("frame enqueued with length " + frame.Length); 

     } 
     } 
    }); 
    childSocketThread.Start(); 
    } 
}).Start(); 

却突然br.ReadInt32();返回一个非常大的长度,以便br.Read(buf, 0, buf.Length);需要很长的实时写入内存流,并在帧内写入错误的数据。

这是客户端:

TcpClient client = new TcpClient(); 
client.Connect(new IPEndPoint(IPAddress.Loopback, 20000)); 
NetworkStream ns = client.GetStream(); 
BinaryWriter bw = new BinaryWriter(ns); 
while (true) 
{ 
    byte[] frame = Screenshot(); 

    bw.Write(frame.Length); 
    Console.WriteLine("a frame length has flushed : " + frame.Length); 

    bw.Write(frame); 
    Console.WriteLine("a frame itself has flushed"); 
} 

Console.ReadKey(); 

,这里的调试信息:

enter image description here

回答

0

如果您检查您收到的十六进制值 - 1196314761 - 你会得到0x474E5089和最后转换为ASCII码,你会得到GNP\x89,它给了我们已知的神奇值\x89PNG这是PNG文件的标记。你实际上是在阅读截图的内容作为长度。

确保您读取数据的代码不会从前一帧读取太多。我认为你读取数据的代码不包括这样一个事实,即你可能会在一个.Read中获得2帧的内容,但之后你只是不在乎数据是否过多。你只检查它是否不小于长度。

+0

非常感谢你,,,它似乎是读取帧数据而不是长度,这是因为我没有检查缓冲区是否适合数据,现在的代码工作得很好 –

相关问题