2014-05-17 15 views
1

我目前正在開發一個C#程序,它允許用戶通過網絡發送文件並在另一端重新組合。除了幾個字節被錯誤地放置在目的地之外,它的工作狀態都很好,並且它不像它開始的那樣是相同的文件。 (例如破壞圖像)。 編輯:至少當它在我的電腦上時,我注意到錯誤可以通過讓客戶端等待一秒鐘之後纔開始從流中讀取來解決,這讓我覺得客戶端偶爾會到達流的末尾,讀取別的東西。任何想法如何以一種更好的方式解決這個問題,而不是像其他計算機那樣等待一秒鐘,我不知道這是否會奏效。 我的服務器中的代碼如下:TCP文件傳輸 - 幾個字節錯誤

TcpListener listener = new TcpListener(13); 
     listener.Start(); 
     FileStream inputStream = File.OpenRead(loadLocation.Text);//loadLocation being a text box with the file path 
     FileInfo f = new FileInfo(loadLocation.Text); 
     int size = unchecked((int)f.Length);//Get's the file size in Bytes 
     int csize = size/4096;//Get's the size in chunks of 4kb; 

      statusLabel.Text = "Waiting for connection..."; 
      TcpClient client = listener.AcceptTcpClient(); 
      statusLabel.Text = "Connection accepted."; 
      NetworkStream ns = client.GetStream(); 
      byte[] byteSize = BitConverter.GetBytes(size);//Sends the number of bytes to expect over the network 
      try 
      { 
       ns.Write(byteSize, 0, byteSize.Length); 
       byte[] temp = new byte[4096]; 
       for (int i = 0; i < csize; i++) 
       { 
        inputStream.Read(temp, 0, 4096); 
        ns.Write(temp, 0, 4096); 
       } 
       byte[] end = new byte[size % 4096]; 
       inputStream.Read(end, 0, size % 4096); 
       ns.Write(end, 0, size % 4096); 
       ns.Close(); 
       inputStream.Close(); 
       client.Close(); 
       done = true; 
       statusLabel.Text = "DONE!"; 
      } 
      catch (Exception a) 
      { 
       Console.WriteLine(a.ToString()); 
      } 
     listener.Stop(); 

客戶端代碼如下:

try 
     { 
      FileStream outputStream = File.OpenWrite(saveLocation.Text); 
      TcpClient client = new TcpClient("127.0.0.1", 13); 

      NetworkStream ns = client.GetStream(); 

      byte[] byteTime = new byte[sizeof(int)]; 
      int bytesRead = ns.Read(byteTime, 0, sizeof(int)); 
      int size; 
      size = BitConverter.ToInt32(byteTime, 0); 
      int csize = size/4096; 
      byte[] temp = new byte[4096]; 
      for (int i = 0; i < csize; i++) 
      { 
       ns.Read(temp, 0, 4096); 
       outputStream.Write(temp, 0, 4096); 
      } 
      byte[] end = new byte[size % 4096]; 
      ns.Read(end, 0, size % 4096); 
      outputStream.Write(end, 0, size % 4096); 
      ns.Close(); 
      outputStream.Close(); 
      client.Close(); 
      statusLabel.Text = "DONE!"; 

     } 
     catch (Exception a) 
     { 
      Console.WriteLine(a.ToString()); 
     } 

我知道,TCP保證交付的訂單,因此我不知道這可能是可能導致輸出文件的問題。值得注意的另一個值得注意的地方是,每次傳輸圖像時,腐敗都會有所不同,在圖像上的不同位置會出現大的標記。

回答

1

你的代碼應該考慮到,一個NetworkStream(和大多數TCP sockets一般)不一定返回最初請求的全部字節數。

微軟writes:如可用,直到 數由大小參數指定的字節

讀操作讀取儘可能多的數據。

在您的讀取操作周圍添加一個外部循環以確保緩衝區實際填充。更多的錯誤處理也是可取的。

也許,你可以從類似的question+answer得到一些靈感。它顯示了這樣一個外環的外觀。

+0

非常感謝,如果我有更多的聲望,我會爲您的答案投票。 – Jack