2012-06-15 61 views
2

首先,讓我解釋我的情況:我正在使用套接字進行通信的C#中的客戶端和服務器上工作。從C中的緩衝區中檢索多個對象#

出於實際原因,我使用兩個套接字的異步部分將二進制序列化對象從客戶端傳輸到服務器,反之亦然。

我的問題是,當我一次發送太多對象時,接收器對象「堆棧」到緩衝區中,當我嘗試反序列化緩衝區內容時,它只給我一個對象。

我的問題是:我怎樣才能將每個對象從緩衝區中分離出來?

這裏是我的ReceiveCallback功能:

private void ReceiveMessageCallback(IAsyncResult asyncResult) 
    { 
     Socket socket = (Socket)asyncResult.AsyncState; 
     try 
     { 
      int read = socket.EndReceive(asyncResult); 
      if (read > 0) 
      { 
       Log("Reception of " + read + " Bytes"); 

       // Jumper is an object that I use to transport every message 
       Jumper pod = Common.Serializer.DeSerialize<Jumper>(this.readbuf); 

       Buffer.SetByte(this.readbuf, 0, 0); 
       socket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None, new AsyncCallback(ReceiveMessageCallback), socket); 

       //We fire an event to externalise the analyse process 
       Receiver(pod, socket); 
      } 
     } 
     catch (SocketException ex) 
     { 
      if (ex.SocketErrorCode == System.Net.Sockets.SocketError.ConnectionReset) 
      { 
       socket.Close(); 
       Log("Distant socket closed"); 
      } 
      else 
       Log(ex.Message); 
     } 
     catch (Exception ex) 
     { 
      Log(ex.Message); 
     } 
    } 
+1

問題可能是發件人代碼。你能發佈發送對象的代碼嗎?確保在每個對象發出後刷新套接字 – GETah

+0

@GETah +1具有相同的想法和更多細節。 – Mualig

回答

0

反序列化會消耗你的緩衝區的一個對象,並會留在下一對象的開始「讀指針」的緩衝區。

我的建議是要麼:從插座流到一些其它的(存儲器)

  • 移動數據緩衝器並從那裏反序列化,並用手有超過整個「緩衝」控制

  • 當你得到一個回調時,在一行中調用反序列化幾次,直到你得到一個異常。

第二條本辦法很可能會失敗,因爲沒有人可以保證,你總是會得到一次性全對象,因爲這是連接到插座流是字節序列,它可以在任何時候被打破。

希望有一定道理。

編輯:

事實上,要做到這一點正確的事情是將封裝每個「信息」(上發送序列化對象)到一個數據包,其中,例如你有一個小的頭,告訴你數據包的長度,接收後,您將讀取套接字流,直到您有完整的數據包數據,然後序列化。然後是下一個數據包,依此類推。

更:

說你在1000個字節的速率發送方發送的數據插入插座。在接收端,你可能永遠由1000個字節獲得了1000座,其實你可以預期,只有在兩個條件:每間

  • 延遲發送是非常大的,並且在發送念之間發生在接收器
  • 純粹意外
+1

僅僅因爲您從套接字接收到一些數據並不意味着您已收到邏輯事務中的所有數據。我同意第1部分和編輯。使用長度計數器跟蹤您的數據。讀入緩衝區,直到確保已收到所有數據。然後反序列化邏輯事務中的對象。 –