如何在网络流中写入一个小间隙?

How do I write a small gap in networkstream?

我有一个服务器,它通过 NetworkStream 将不同大小的遥测数据发送到接收器,或者我称之为客户端。我的目标是最大速度,所以我希望延迟最少。频率是不受控制的,所以我想在我的客户中使用一个无限循环,它使用 NetworkStream.Read 来读取数据,处理它,然后重复。

我的问题是,有时,如果两个数据包的发送速度非常快,而客户端的互联网连接速度较慢,那么这两个数据包将作为连续流接收,从而导致无法处理数据。我发现的一个半解决方案(主要是为了确认这确实是错误)是每次传输都有一个小的延迟 after/before,使用 System.Threading.Thread.Sleep(100),但不仅我发现 Sleep 有问题解决方案,它是不一致的,因为它还会降低连接良好的客户端的速度,并且问题可能会持续存在更糟糕的连接。

我想要做的是让服务器在每次传输之间发送一个间隔,提供一个分隔,而不管互联网速度如何,因为 NetworkStream.Read 应该在当前连续流结束后完成。我不太了解 NetworkStream 的工作原理,也不知道几个字节的空流是什么样的,也不知道如何实现。有什么想法吗?

如果可能的话,我强烈建议您更改协议。 TCP 一种基于流的协议,任何有效忽略它的尝试都可能是不可靠的。

相反,我建议将其更改为消息流,其中每条消息都有一个前缀,表示消息正文的长度。这样一来,特定消息是否被拆分为多个数据包或与其他消息在同一数据包中接收都无关紧要。它还使客户的阅读更容易:他们确切地知道要读取多少数据,因此可以在一个简单的循环中完成。

如果您担心长度前缀会引入太多开销(如果数据通常很小),您可能会使用包含整批信息(多个遥测项目)的单个消息使协议稍微复杂一些).

但从根本上说,值得假设数据拆分成多个数据包,再次组合等。不要假设一个写入操作对应一个读取操作。

您没有特别提及您在 NetworkStream 上使用的 ProtocolType,但 TCP 肯定无法满足您的要求。中级 routers/switches 无法知道您的意图是按时间分隔数据包,并且不会尊重这种愿望。此外,TCP 是面向流的,按顺序传送数据包,并且它对丢失的数据包和损坏的数据包进行纠错。在任何一个或另一个发生时,它将保留所有进一步的数据包,直到重新传输错误数据包 - 然后你可能会把它们全部放在一起。

使用 UDP 并在 接收(即客户端)端实施节流 - 如果落后则丢弃数据。