C# 如何在networkstream中写入一个小间隙?

C# 如何在networkstream中写入一个小间隙?,c#,server,networkstream,pause,C#,Server,Networkstream,Pause,我有一个服务器,它通过NetworkStream将不同大小的遥测数据发送给接收器,或者我称之为客户端。我的目标是最大的速度,所以我希望最小的延迟。频率是不可控的,所以我想在我的客户机中使用无限循环,它使用NetworkStream.Read读取数据,处理它,然后重复 我的问题是,有时,如果两个数据包发送得非常快,而客户端的internet连接速度很慢,那么这两个数据包将作为连续流接收,从而产生无法处理的数据。我发现的一个半解决方案(主要是为了确认这确实是错误)是使用System.Threadin

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

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


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

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

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

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


但从根本上说,值得假设数据将被拆分为多个数据包,然后再进行组合等。不要假设一个写操作对应一个读操作。

您没有特别提到您在
网络流上使用的
协议类型,但TCP肯定会满足您的要求。中间路由器/交换机无法知道您的意图是按时间分离数据包,并且不会尊重这一愿望。此外,TCP是面向流的,它按顺序传递数据包,并且对丢弃的数据包和损坏的数据包具有纠错功能。一旦出现一个或另一个错误,它将保留所有其他数据包,直到错误数据包被重新传输——然后您可能会得到一堆数据包


使用UDP并在接收端(即客户端)实现限制-如果落后,则抛出数据

我对这种方法的担忧是,在这里进行多次传输的目的是获得最新的信息。如果我接收到一个连续的流,然后将其分离,那么只有最后一部分是相关的。如果我能在阅读时把它分开,所有的传输都可以用来提高精度。@Fireball教授:恐怕我不太明白。您可以根据需要设计协议,但重要的一点是在发送之前指定要发送的数据量,以便接收方能够了解要读取的数据量。我想我需要更多的上下文来理解你的评论,但我怀疑这会使我的建议不可行。读了一些书,UDP确实是我应该使用的。这是我的另一个问题,解决方案是没有解决方案,做些别的事情。UDP有它自己的问题需要注意:它会丢弃数据包并按顺序发送它们。第一个问题对你来说可能不是问题,你可以用数据包中的时间戳/序列号来修复第二个问题。@Fireball教授,当然有一个解决方案,正如另一个答案中很好地概述的那样。如果您正确使用TCP,它可以很好地用于您要做的事情。