c# - 从 C# 中的缓冲区中检索多个对象

标签 c# sockets serialization asynchronous buffer

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

最佳答案

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

我的建议是:

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

  • 当你得到一个回调时,连续多次调用反序列化,直到你得到一个异常。

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

希望这是有道理的。

编辑:

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

更多:

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

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

关于c# - 从 C# 中的缓冲区中检索多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11053983/

相关文章:

c# - WPF 双动画无法正常工作 C#

c# - 类型未映射 Entity Framework 5.0

c# - 用其他XAML文件中的网格替换内容WPF网格控件

C Socket 下载 .exe 大 6 倍?

java - GSON GraphAdapterBuilder 接口(interface)失败

java - jackson :仅序列化标记的字段

c# - 如何从当前 View 引用另一个 View ?

java - 在运行时添加jbutton

Android Studio 拍照后通过套接字发送字符串 [Google Glass]

c# - 序列化/反序列化 System.RuntimeType