Ent*_*ity 0 c# networkstream fragment beginread
我有一个TCP网络程序,它通过连接发送已经序列化并编码到base64的大对象.我写了一个客户端库和一个服务器库,他们都使用NetworkStream's Begin/EndRead和Begin/EndWrite.这是我正在使用的代码(非常简化的版本):
对于服务器:
var Server = new TcpServer(/* network stuffs */);
Server.Connect();
Server.OnClientConnect += new ClientConnectEventHandler(Server_OnClientConnect);
void Server_OnClientConnect()
{
LargeObject obj = CalculateLotsOfBoringStuff();
Server.Write(obj.SerializeAndEncodeBase64());
}
Run Code Online (Sandbox Code Playgroud)
然后客户:
var Client = new TcpClient(/* more network stuffs */);
Client.Connect();
Client.OnMessageFromServer += new MessageEventHandler(Client_OnMessageFromServer);
void Client_OnMessageFromServer(MessageEventArgs mea)
{
DoSomethingWithLargeObject(mea.Data.DecodeBase64AndDeserialize());
}
Run Code Online (Sandbox Code Playgroud)
客户端库有一个回调方法,NetworkStream.BeginRead用于触发OnMessageFromServer将数据作为字符串传递的事件MessageEventArgs.
BeginRead/EndRead但是,当通过它接收大量数据时,它似乎在多个消息上分散.EG假装这是一条很长的信息:
"This is a really long message except not because it's for explanatory purposes."
Run Code Online (Sandbox Code Playgroud)
如果这确实是一个很长的消息,Client_OnMessageFromServer可能会被称为...说"三条消息"的碎片部分:
"This is a really long messa"
"ge except not because it's for explanatory purpos"
"es."
Run Code Online (Sandbox Code Playgroud)
Soooooooo ...... 深吸一口气
通过Begin/EndWrite一次通话接收所有内容的最佳方式是什么Client_OnMessageFromServer?
你不能.在TCP上,事物的到达方式不一定与发送方式相同.您的代码的工作是知道什么构成完整的消息,并且如果有必要缓冲传入的数据,直到您有完整的消息(注意不要丢弃下一个消息的开始我的过程).
在文本协议中,这通常意味着"发现换行符/ nul-char".对于二进制,它通常意味着"读取消息的前导码中的长度标题".