2010-01-25 26 views
3

我在那裏我試圖同時在我的套接字接收數據增長的字節數組代碼的時候,只不過是想增加字節數組時失敗,但確定。這是錯誤的。發送通過套接字大序列化對象使用一個巨大的字節數組

public bool ReceiveObject2(ref Object objRec, ref string sErrMsg) 
    { 
     try 
     { 
      byte[] buffer = new byte[1024]; 
      byte[] byArrAll = new byte[0]; 
      bool bAllBytesRead = false; 

      int iRecLoop = 0; 

      // grow the byte array to match the size of the object, so we can put whatever we 
      // like through the socket as long as the object serialises and is binary formatted 
      while (!bAllBytesRead) 
      { 
       if (m_socClient.Receive(buffer) > 0) 
       { 
        byArrAll = Combine(byArrAll, buffer); 
        iRecLoop++; 
       } 
       else 
       { 
        m_socClient.Close(); 
        bAllBytesRead = true; 
       } 
      } 

      MemoryStream ms = new MemoryStream(buffer); 
      BinaryFormatter bf1 = new BinaryFormatter(); 
      ms.Position = 0; 
      Object obj = bf1.Deserialize(ms); 
      objRec = obj; 

      return true; 
     } 
     catch (System.Runtime.Serialization.SerializationException se) 
     { 
      objRec = null; 
      sErrMsg += "SocketClient.ReceiveObject " + "Source " + se.Source + "Error : " + se.Message; 
      return false; 
     } 
     catch (Exception e) 
     { 
      objRec = null; 
      sErrMsg += "SocketClient.ReceiveObject " + "Source " + e.Source + "Error : " + e.Message; 
      return false; 
     } 
    } 

    private byte[] Combine(byte[] first, byte[] second) 
    { 
     byte[] ret = new byte[first.Length + second.Length]; 
     Buffer.BlockCopy(first, 0, ret, 0, first.Length); 
     Buffer.BlockCopy(second, 0, ret, first.Length, second.Length); 
     return ret; 
    }  

錯誤:mscorlibError:輸入流不是有效的二進制格式。起始內容(以字節爲單位)是:68-61-73-43-68-61-6E-67-65-73-3D-22-69-6E-73-65-72 ...

然而,當我只是欺騙並使用MASSIVE緩衝區大小的罰款。

 public bool ReceiveObject(ref Object objRec, ref string sErrMsg) 
    { 
     try 
     { 
      byte[] buffer = new byte[5000000]; 

      m_socClient.Receive(buffer); 
      MemoryStream ms = new MemoryStream(buffer); 
      BinaryFormatter bf1 = new BinaryFormatter(); 

      ms.Position = 0; 
      Object obj = bf1.Deserialize(ms); 
      objRec = obj; 

      return true; 
     } 
     catch (Exception e) 
     { 
      objRec = null; 
      sErrMsg += "SocketClient.ReceiveObject " + "Source " + e.Source + "Error : " + e.Message; 
      return false; 
     } 
    } 

這真的讓我很難過。我不知道爲什麼它不工作。我已經從這裏提出了一個建議,所以我很確定這不是做錯事情?

我希望有人能指出我要去的地方錯了

回答

2

Combine方法是一個非常昂貴的方法來增長一個數組,尤其是當MemoryStream設計來解決這個;和對方回覆是正確的:你必須檢查的字節數讀:

using(MemoryStream ms = new MemoryStream()) { 
    int bytesRead; 
    while((bytesRead = m_socClient.Receive(buffer)) > 0) { 
     ms.Write(buffer, 0, bytesRead); 
    } 
    // access ms.ToArray() or ms.GetBuffer() as desired, or 
    // set Position to 0 and read 
} 

當然,你可以只從流(它傳遞給你的讀者)

又讀直接 - 如果你的序列號太大,你可能會考慮替代編碼器,比如protobuf-net(儘管這會稍微改變代碼)。這可以解決一個巨大的對象的問題。

+0

Gaargh!我認爲這將是答案。不幸的是,它現在讀入循環並在沒有剩餘字節時掛起。我不知道爲什麼會發生這種情況,因爲我認爲它會返回零然後退出。 – FinancialRadDeveloper 2010-01-26 11:02:09

+0

我想我會需要檢查讀取的字節,如果這是比緩衝區小於退出循環爲讓到它掛結束。我想它等待另一個發送,因爲它完成了第一個接收,如果你打電話給另一個,那麼你會期待另一個數據加載。 – FinancialRadDeveloper 2010-01-26 11:45:18

+1

@AlanR - 在這種情況下,請檢查遠程流是否已關閉。如果意圖將其打開,那麼是的:您需要通過一定數量的數據跟蹤自己的進度。 – 2010-01-26 12:38:35

1

我不是很熟悉C#網絡,但不是你每次調用Combine()時附加全1024個字節的緩衝區,而忽略數的字節從套接字讀取?您可能至少需要一個額外的參數來告知要從second複製多少個字節。

+0

@尼古拉緩衝器是固定爲1024字節和I * *應該被添加此到byArrAll。因此,大量的緩衝區obv浪費了空間,組合數組也是如此。如果你趕上我的漂移,那麼合併後的陣列應該是最大1023? – FinancialRadDeveloper 2010-01-25 18:32:19

+1

您應該添加從套接字中讀取的字節數,該數字小於或等於1024。 – 2010-01-25 18:53:46

相關問題