【问题标题】:Retrieve multiple objects from a buffer in C#从 C# 中的缓冲区中检索多个对象
【发布时间】:2012-06-15 23:51:53
【问题描述】:

首先,让我解释一下我的情况:我正在使用 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);
        }
    }

【问题讨论】:

  • 问题可能出在发件人代码中。你能发布发送对象的代码吗?确保在发送每个对象后刷新套接字
  • @GETah +1 有相同的想法,并提供更多细节。

标签: c# sockets serialization asynchronous buffer


【解决方案1】:

反序列化将占用一个对象的缓冲区,并将缓冲区的“读取指针”留在下一个对象的开头。

我的建议是:

  • 将数据从套接字流移动到其他(内存)缓冲区并从那里反序列化,并手动控制整个“缓冲”

  • 收到回调时,连续多次调用反序列化,直到收到异常为止。

第二种方法很可能会失败,因为没有人能保证您总是一次获得全部对象,因为附加到套接字的流是一个字节序列,它可能随时被破坏。

希望这有点道理。

编辑:

事实上,正确的做法是将每个“消息”(发送时的序列化对象)封装到一个数据包中,例如,您将有一个小标题告诉您数据包的长度,然后接收,您将读取套接字流,直到您有完整的数据包数据,然后序列化。然后是下一个数据包,以此类推。

更多:

假设您在发送方以 1000 字节的速率将数据发送到套接字中。在接收端,您可能永远不会从套接字中获得 1000 x 1000 字节,事实上,您只能在两种情况下预期:

  • 每次发送之间的延迟非常大,发送之间的读取发生在接收端
  • 纯属意外

【讨论】:

  • 仅仅因为您从套接字接收到一些数据并不意味着您已经从逻辑事务中接收到所有数据。我同意第 1 部分和编辑。使用长度计数器跟踪您的数据。读入缓冲区,直到您确保已收到所有数据。然后反序列化逻辑事务中的对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 2012-05-27
  • 2012-03-09
相关资源
最近更新 更多