2012-03-02 31 views
1

我有一個將文件發送到服務器的客戶端應用程序。問題是,在客戶端部分文件被正確讀取,我可以保存字節數組後,我讀它,並保存爲一個有效的JPG。但是,在服務器端,某些地方的數據被破壞。我所做的就是不斷向列表中添加所有傳入數據,直到客戶端關閉連接。TCP客戶端 - 數據僅在某些部分被損壞

我重疊發送客戶端和服務器/接收數據,正如你可以看到有地方數據不匹配的地方:http://s16.postimage.org/mtmm1hssl/corrupted_data.png

我不明白,這怎麼可能,我使用的是大緩衝區和圖像相當小,所以即使服務器在一個「塊」中接收到圖像,數據仍然被破壞。

任何想法爲什麼會發生這種情況?

UPDATE:

客戶端:

我獲取的圖像與HttpWebRequest的:

    List<byte> test_buffer = new List<byte>(); 

        using (Stream MyResponseStream = hwresponse.GetResponseStream()) 
        { 
         byte[] MyBuffer = new byte[4096]; 
         int BytesRead; 

         while (0 < (BytesRead = MyResponseStream.Read(MyBuffer, 0, MyBuffer.Length))) 
         { 

          for (int i = 0; i < BytesRead; i++) 
          { 
           test_buffer.Add(MyBuffer[i]); // just for testing 
          } 

          TCP_R.SendBytes(MyBuffer); // send data back to server 
         } 
        } 

        TCP_R.Close(); // tell server that we're done sending data 

TCP_R是處理所有的TCP東西類(連接到服務器/發送數據)

這是TCP_R.SendBytes函數:

public void SendBytes(Byte[] data) 
    { 
     try 
     { 
      if (m_clientSocket != null) 
      { 
       m_clientSocket.Send(data); 
      } 

     } 
     catch (SocketException se) 
     { 
      log("send_bytes err: " + se.Message); 
     } 
    } 

通知我以前test_buffer收集所有的字節是否被正確接收的一切來驗證。如果我使用此代碼:

    MemoryStream ms = new MemoryStream(test_buffer.ToArray()); 
        Image returnImage = Image.FromStream(ms); 
        returnImage.Save("image.jpg"); 

圖像已成功創建。所以我假設客戶端正確地發送數據。

服務器端:

public void OnDataReceived(IAsyncResult asyn) 
    { 

     try 
     { 
      SocketPacket socketData = (SocketPacket)asyn.AsyncState; // cast 

      int iRx = 0; 

       iRx = socketData.m_currentSocket.EndReceive(asyn); 
       char[] chars = new char[iRx + 1]; 

       System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); // CAN THIS BE CAUSING THE PROBLEM!?! 
       int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0); 


       for (int s = 0; s < charLen; s++) 
       { 

        RESPONSE_DATA.Add(socketData.dataBuffer[s]); // Collect response data 

       } 

       WaitForData(socketData.m_currentSocket, socketData.socket_id, REQUEST_INDEX_ID); 

      } 

     } 
     catch (ObjectDisposedException) 
     { 

     } 
     catch (SocketException se) 
     { 

     } 
    } 

UPDATE2:

我使用OnDataReceived功能和REQUEST_RESPONSE這是List<byte>建立的所有數據收集數據 看來,這些生產線造成問題:

   System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); // CAN THIS BE CAUSING THE PROBLEM!?! 
       int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0); 

如何在不使用解碼器的情況下將數據提取到socketData.dataBuffer中?

解決方案: 雖然我是直接從DataBuffer中,讀「d.GetChars(socketData.dataBuffer ..」線不知何故搞砸了緩衝區,爲此我被搞砸了我的數據仍然需要使用則GetChars太閱讀包作爲字符串的第一部分,所以我只是改變:

int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0); 

到:

byte[] tmp_a = new byte[socketData.dataBuffer.Length]; 
tmp_a = socketData.dataBuffer; 
int charLen = d.GetChars(tmp_a, 0, iRx, chars, 0); 

而現在一切工作順利進行。顯然不知何故直接調用緩衝區getChars影響緩衝區。

+0

向我們展示一些代碼。如果你遺漏了所有的細節,你不能指望我們回答這個問題。 – usr 2012-03-02 16:02:53

+0

我懷疑你的代碼在客戶端或服務器上有問題。不幸的是,您沒有向我們展示客戶端或服務器代碼,這使得很難說明... – 2012-03-02 16:03:07

+0

需要查看您的代碼...發送和接收。 – 2012-03-02 16:03:32

回答

2

聽起來像一個編碼問題。

這裏的關鍵概念是編碼用於文本,圖像不是文本。

不要在發送之前或接收之後嘗試對字節進行編碼或解碼。

同樣,如果您從文件讀取圖像或向文件寫入圖像,請勿嘗試編碼或解碼,請使用二進制模式。

只是不嘗試將字節轉換爲字符,沒有有意義的方式來這樣做。

+0

這是純粹的猜測。特別是,通過tcp發送原始的二進制數據不應該涉及任何編碼。 – 2012-03-02 16:05:49

+0

這個問題不適用於猜測。 – 2012-03-02 16:17:33

+0

是的,它不應該涉及任何編碼,這就是爲什麼我認爲編碼可能是問題。 – 2012-03-02 16:18:45