2017-06-15 85 views
0

Send - Socket.send(ToSend);C#Stream Dictionary問題

public static byte[] ToSend() { 
    Dictionary<int, int> D = new Dictionary<int, int>() { {1,10},{2,88} }; 
    List<int> L = new List<int>() { {22}, {44} }; 
    var binFormatter = new BinaryFormatter(); 
    var mStream = new MemoryStream(); 
    binFormatter.Serialize(mStream, D); 
    //binFormatter.Serialize(mStream, L); 
    return mStream.ToArray(); 
} 

接收 - (與異步)如果(Socket.EndReceive(AR)> 0){荷重(字節);}

public static void Load(byte[] bytes) { 
     var mStream = new MemoryStream(); 
     var binFormatter = new BinaryFormatter(); 
     mStream.Write(bytes, 0, bytes.Length); 
     mStream.Seek(0, SeekOrigin.Begin); 
     var myObject = binFormatter.Deserialize(mStream) as Dictionary<int, int>; 
     //var myObject = binFormatter.Deserialize(mStream) as List<int>; 
     Console.WriteLine(">> " + myObject[1]); 
    } 

問題:列表是工作正常,但不解釋,引發異常如: 「在分析完成之前,遇到了流的末尾。」 有人能告訴我爲什麼嗎?哪裏有問題?哈希表也適用於上面的代碼。爲什麼Dictionarys不?

編輯:發送是在客戶端調用後簡單發送();只是爲了測試。

socket.Send(ToSend()); 

接收是在服務器端使用:

socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(this.RecMessage), this); 

RecMessage看起來是這樣的:

if (socket.EndReceive(result) > 0) {Message Msg = new Message(buffer);} 

在信息很簡單:

Public Message(byte[] buffer){Load(buffer);} 

哈希表的工作,列表正在工作,Int,String或無論我使用的是工作,但不是字典。也許是開始和結束接收的問題?

編輯2:改變緩衝區到[2048]解決了問題,所以問題是開始和編輯接收。它應該如何正確構建?

+0

這適用於我沒有異步,你可能在ToSend(...)完成之前調用Load(...)?這可以解釋爲什麼列表工作和詞典沒有,因爲列表分散到221字節和1369字節,並且很可能完成較慢的封裝;這些信息很少能夠確定地知道,你可以展示你如何使用ToSend(...)和Load(...)的上下文 – NLindbom

+0

你假設一個Send()對應於一個Receive()。它沒有。你需要發明一個成幀協議,或者更確切地說,使用比套接字更高級的結構。看看Protocol Buffers(protobuf-net)。 – CodeCaster

回答

0

好的,解決了。發送和緩衝區管理器收到時,我添加了前綴:

const int PrefixSize = 4; 
    bool prefixSet = false; 
    public int DataSize = 0; 
    int RecLength = 0; 
    byte[] Received = new byte[2048]; 

     try { 
      int dataRead = socket.EndReceive(ar); 
      if (dataRead > 0) { 
       Buffer.BlockCopy(buffer, 0, Received, RecLength , dataRead); 
       RecLength += dataRead; 
       if (RecLength >= PrefixSize) { 
        if (!prefixSet) { 
         prefixSet = true; 
         DataSize = BitConverter.ToInt32(Received, 0); 
        } 
        if (RecLength >= DataSize) { 
         RecLength = 0; prefixSet = false; 
         byte[] data = new byte[DataSize]; 
         Buffer.BlockCopy(Received, 4, data, 0, DataSize); 
         ReceiveNextMessage(); 
         Message m = new Message(this, data); 
        } 
        else { 
         ReceiveNextMessage(); 
        } 
       } 
       else { 
        ReceiveNextMessage(); 
       } 
      } 

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

也許有人覺得這很有用。