【问题标题】:Detect what data is (not yet) received by client on TCP stream in C#检测客户端在 C# 中的 TCP 流上(尚未)接收到哪些数据
【发布时间】:2015-03-22 09:25:45
【问题描述】:

我有一个产生数据的服务器,客户端接收这些数据。只是服务器太快了,客户端超载了。最终,服务器将阻止他的发送操作。

现在,我对来自服务器的旧数据并不真正感兴趣,相反,服务器可以跳过一些消息,只发送对客户端真正重要的信息。

在客户端,我可以使用Client.Available 找出流中还剩下多少数据,但我不知道如何在服务器/发送方上获取这个数字。我可以更改 SendBufferSize,但我会知道 SendBuffer 中有多少可用空间并相应地做出反应。

我可以让客户报告他落后了多少,但这感觉就像在应用程序级别重新发明了 TCP 协议。另外,我不相信已经很慢的客户端会及时警告我的服务器。

有什么方法可以读取 TCP 使用/未使用的窗口大小或发送缓冲区?

【问题讨论】:

  • “我对来自服务器的旧数据并不感兴趣,相反,服务器可以跳过一些消息” - 使用 UDP。
  • 哎呀,不,服务器发送的所有数据都应该到达,我说我可以跳过消息,而不是跳过数据包。
  • 那不计算。一条消息可以跨越一个或多个数据包,因此如果您可以跳过消息,则可以跳过数据包。 TCP是不能跳过的流,所以如果一定要能跳过,就不能用TCP。
  • 一个数据包也可以跨越一个或多个消息,另外,如果一个消息跨越多个数据包,丢弃半个消息是不安全的,更不用说我不想手动重新排序我的数据包客户到达时出现故障。 TCP 为我做了这一切,这很好。
  • “我不想”并不是“你必须”的真正答案。使用 TCP,你必须按顺序消费所有的数据包,但如果你想实时这样做,你必须更快地消费,这是你做不到的。但是,您可以创建另一个“ack”层;让客户端告诉服务器它已经收到一条消息,如果服务器确定客户端滞后,让服务器跳过发送消息。

标签: c# .net tcp stream


【解决方案1】:

TcpClient.SendTimeout 设置为合理的值。如果客户端在超时到期之前不接受并消费消息,Write 方法(及其重载)将抛出SocketException。您应该编写一个 catch-block,然后决定是重试操作还是丢弃消息。

【讨论】:

  • 我已经考虑过了,但是我怎么知道我的流是否仍然处于安全状态?在引发异常之前,它可能已经发送了一半的上一条消息。
  • 您的客户端应该一次性使用整条消息,以便它接受每条消息的所有字节或不接受任何字节。
  • 当在超时之前写入超过 0 个字节时,流变得不可用是正确的。这是您可以检测到的客户端错误,但无法从服务器端恢复。发生这种情况时,您应该始终关闭连接。
  • 是的,很遗憾。我可能最终牺牲了处于等待状态的线程,或者以某种方式将其包装在异步调用中。令我惊讶的是,您无法访问剩余的窗口大小,我会继续寻找一些东西。无论如何,感谢您与我一起思考。
  • 您可以记录写入的字节数,并显式调用Stream.Flush() 以在关键间隔(例如,在每条消息之间)清除传出缓冲区。写入的字节数应该直接对应于客户端可用的字节数。
【解决方案2】:

“最终,服务器将阻止他的发送操作”

坦率地说,以上是这里真正的错误。没有理由仅仅因为某些客户端没有足够快地接收数据而阻止服务器。服务器应使用非阻塞、异步 I/O,否则应继续正常工作,即使客户端读取速度不够快。


现在,即使您解决了阻塞问题,您也可能遇到客户端接收数据不够快的问题。 IE。正如您所提到的,您希望客户端不接收它无法处理的数据。您在这里至少有几个选择:

  • 要求客户端在发送另一条消息之前主动响应已处理的消息。

赞成:这是一个直接的解决方案,因为服务器永远不会超过客户端可以处理的传输速率。
反对:这会为您的网络协议增加带宽开销和延迟。 ping 时间长的客户端会受到影响,即使它能够快速接收数据。

  • 跟踪客户端似乎能够处理的数据速率,并减慢消息的实现速度,以使服务器不超过此速率。

赞成:此解决方案将始终保持客户端能够处理的最高传输速率。
反对:至少在最初,并且也许随着客户自身能力的间歇性变化,这可能会暂时超出客户跟上的能力

  • 使用 UDP,这将允许网络传输层丢弃客户端处理速度不够快的数据报。

优点:此解决方案将整个问题委托给网络传输层,让您不必担心服务器和客户端的真实细节
缺点: UDP本质上是不可靠的。除了处理丢弃的数据报(在您的情况下这是一个好处),您还必须准备好处理收到的乱序数据报,以及多次收到的单个数据报。

考虑到广泛陈述的问题,这是尽可能具体的答案。

【讨论】:

    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    相关资源
    最近更新 更多