2017-08-29 48 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

非常感謝你,,,它似乎是讀取幀數據而不是長度,這是因爲我沒有檢查緩衝區是否適合數據,現在的代碼工作得很好 –

相關問題