gpt4 book ai didi

c# - 在不关闭或处理流的情况下通过 TCP 发送多个对象

转载 作者:可可西里 更新时间:2023-11-01 02:47:08 27 4
gpt4 key购买 nike

我曾使用 BinaryFormatter 通过 NetworkStream 序列化一个对象代码是这样的

//OpenConnection ...
TCPClient client = server.AcceptTCPConnection();
Message message = new Message("bla bla"); // This is the serializable class
NetworkStream stream = client.GetStream(); // Get Stream
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, message);
stream.Flush();
stream.Close(); //Close Connection

而在客户端代码中,我们只需要从流中读取bf.Deserialize(stream) 作为消息获取我们刚刚从服务器发送的对象。

但是这里有一个问题,如果我删除 stream.Close(); 行,客户端就无法读取这个对象。或者我可以更改为 stream.Dispose();

但是,我想再次使用这个流来发送另一个Message,我该怎么做?求助,我好头疼@@

更新:我找到了这个问题的原因。因为我用一台机器同时跑client和server。它在两台不同的机器上运行良好。有人可以告诉我为什么吗?几天前遇到这个大问题。

最佳答案

发送多条单独的消息涉及“框架”——将单个 channel 拆分为单独的 block ,这些 block 永远不需要客户端“读完”。不过,奇怪的是,我的印象是 BinaryFormatter 已经实现 基本框架 - 但是:我可能是错的。在一般情况下,当使用二进制协议(protocol)时,最常见的方法是在每条消息前加上有效载荷的长度,即

using(var ms = new MemoryStream()) {
while(...)
{
// not shown: serialize to ms

var len BitConverter.GetBytes((int)ms.Length);
output.Write(len, 0, 4);
output.Write(ms.GetBuffer(), 0, (int) ms.Length);
ms.SetLength(0); // ready for next cycle
}
}

调用者必须:

  • 准确读取 4 个字节(至少,对于上述内容),或检测 EOF
  • 确定长度
  • 准确读取个字节
  • 反序列化
  • 重复

如果这听起来工作量很大,也许只需要使用一个序列化程序来为您完成所有这些工作;例如,对于 protobuf-net,这将是:

while(...) { // each item
Serializer.SerializeWithLengthPrefix(output, PrefixStyle.Base128, 1);
}

读者会是:

foreach(var msg in Serializer.DeserializeItems<Message>(
input, PrefixStyle.Base128, 1))
{
// ...
}

(注意:这不使用与 BinaryFormatter 相同的格式/规则)

关于c# - 在不关闭或处理流的情况下通过 TCP 发送多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19587919/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com