gpt4 book ai didi

c# - 将完整的消息写入 NetworkStream 或写入每条消息的各个部分是个好主意吗?

转载 作者:可可西里 更新时间:2023-11-01 02:33:25 34 4
gpt4 key购买 nike

我想知道将完整消息写入 NetworkStream 是否比在多个 Write 调用中写入消息的每个部分更好。例如,将消息完整地写成这样......

    NetworkStream ns = tcpClient.GetStream();

byte[] message = Encoding.ASCII.GetBytes("This is a message.");
ns.Write(message, 0, message.Length);

...比这样写更好...

    NetworkStream ns = tcpClient.GetStream();

byte[] message1 = Encoding.ASCII.GetBytes("This ");
byte[] message2 = Encoding.ASCII.GetBytes("is ");
byte[] message3 = Encoding.ASCII.GetBytes("a ");
byte[] message4 = Encoding.ASCII.GetBytes("message.");

ns.Write(message1, 0, message1.Length);
ns.Write(message2, 0, message2.Length);
ns.Write(message3, 0, message3.Length);
ns.Write(message4, 0, message4.Length);

每种方法在程序性能或网络性能上是否也有很大差异?

最佳答案

这很棘手,取决于套接字的配置方式。您写的内容不会直接映射到收到的内容:

  • NIC 可能必须在传输时将其拆分为数据包
  • 套接字/NIC 可以配置为合并 数据包以进行传输(减少实际的网络数据包,但很难确定您是否发送了您认为的数据包 - 它可能是本地缓冲)

请特别注意 NetworkStream.Flush() 不执行任何操作,因此您不能使用它来推送任何最后几个字节

一个好的折衷方案是将 NetworkStream 包装在 BufferedStream 中,并使用 NoDelay = true 配置 Socket >(禁用本地输出缓冲)。 BufferedStream 允许您以任意大小的 block (包括单个字节)继续写入,而不会导致巨大的数据包碎片; BufferedStream 将在接近设定大小时自行刷新。然而,重要的是,您现在可以访问 BufferedStreamFlush() 方法,该方法将缓冲数据清空到网络;如果进行复杂的前后对话并且需要知道您已发送完消息,这很有用。

否则的风险是客户端永远等待响应(没有意识到它仍然有 3 个字节在本地缓冲,所以还没有发送完整的请求),并且服务器没有响应,因为它仍在等待请求的最后 3 个字节。死锁。

关于c# - 将完整的消息写入 NetworkStream 或写入每条消息的各个部分是个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9150306/

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