2012-06-15 59 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部分和编辑。使用长度计数器跟踪您的数据。读入缓冲区,直到确保已收到所有数据。然后反序列化逻辑事务中的对象。 –