从 C# 中的缓冲区中检索多个对象
本文关键字:检索 对象 缓冲区 | 更新日期: 2023-09-27 18:37:15
首先,让我解释一下我的情况:我正在开发使用套接字进行通信的 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 字节,实际上您只能在两种情况下预期:
- 每次发送之间的延迟非常大,并且在两次发送之间,读取发生在接收器处
- 纯属意外