检测客户端在 C# 中的 TCP 流上(尚未)接收到哪些数据
Detect what data is (not yet) received by client on TCP stream in C#
我有一个产生数据的服务器,客户端接收这个数据。只是服务器速度太快,导致客户端过载。最终,服务器将阻止他的发送操作。
现在,我对来自服务器的旧数据并不真正感兴趣,相反,服务器可以跳过一些消息,只发送对客户端真正重要的内容。
在客户端上,我可以使用 Client.Available
找出流中剩余的数据量,但我无法弄清楚如何在 server/sender 上获得这个数字。我可以更改 SendBufferSize
,但我想知道 SendBuffer 中有多少 space 可用,并相应地做出反应。
我可以让客户报告他落后了多少,但这感觉就像在应用程序级别重新发明 TCP 协议。另外,我不相信已经很慢的客户端会及时警告我的服务器。
有没有办法读取 TCP used/unused window 大小或发送缓冲区?
将TcpClient.SendTimeout
设置为合理的值。如果客户端在超时到期之前不接受和使用消息,Write
方法(及其重载)将抛出 SocketException
。您应该编写一个 catch 块,然后决定是重试操作还是丢弃消息。
"Eventually, the server will block on his send operations"
老实说,上面才是真正的bug。服务器没有理由仅仅因为某些客户端接收数据的速度不够快而阻塞。服务器应使用非阻塞、异步 I/O,否则应继续正常工作,即使客户端读取速度不够快。
现在,即使您解决了阻塞问题,您也可能会遇到客户端接收数据速度不够快的问题。 IE。正如您提到的,您希望客户端不接收它无法处理的数据。您在这里至少有几个选择:
- 要求客户端在发送另一条消息之前主动响应已处理的消息。
专业人士:这是一个立竿见影的解决方案,因为服务器永远不会超过客户端可以处理的传输速率。
缺点: 这会增加网络协议的带宽开销和延迟。 ping 时间长的客户端会受到影响,即使它能够快速接收数据。
- 跟踪客户端似乎能够处理的数据速率,并减慢消息的具体化,使服务器不超过此速率。
Pro:此解决方案将始终保持客户端能够处理的最高传输速率。
缺点: 至少在最初,并且可能会间歇性地随着客户自身能力的变化而变化,这可能会暂时超出客户跟上的能力
- 使用 UDP,这将允许网络传输层丢弃客户端处理速度不够快的数据报。
专业人士:这个解决方案将整个问题委托给网络传输层,让您担心服务器和客户端的真实细节
缺点: UDP 本质上是不可靠的。除了处理丢失的数据报(在您的情况下这是一个好处),您还必须准备好处理乱序接收的数据报,以及不止一次接收到的单个数据报。
鉴于广泛陈述的问题,这是一个尽可能具体的答案。
我有一个产生数据的服务器,客户端接收这个数据。只是服务器速度太快,导致客户端过载。最终,服务器将阻止他的发送操作。
现在,我对来自服务器的旧数据并不真正感兴趣,相反,服务器可以跳过一些消息,只发送对客户端真正重要的内容。
在客户端上,我可以使用 Client.Available
找出流中剩余的数据量,但我无法弄清楚如何在 server/sender 上获得这个数字。我可以更改 SendBufferSize
,但我想知道 SendBuffer 中有多少 space 可用,并相应地做出反应。
我可以让客户报告他落后了多少,但这感觉就像在应用程序级别重新发明 TCP 协议。另外,我不相信已经很慢的客户端会及时警告我的服务器。
有没有办法读取 TCP used/unused window 大小或发送缓冲区?
将TcpClient.SendTimeout
设置为合理的值。如果客户端在超时到期之前不接受和使用消息,Write
方法(及其重载)将抛出 SocketException
。您应该编写一个 catch 块,然后决定是重试操作还是丢弃消息。
"Eventually, the server will block on his send operations"
老实说,上面才是真正的bug。服务器没有理由仅仅因为某些客户端接收数据的速度不够快而阻塞。服务器应使用非阻塞、异步 I/O,否则应继续正常工作,即使客户端读取速度不够快。
现在,即使您解决了阻塞问题,您也可能会遇到客户端接收数据速度不够快的问题。 IE。正如您提到的,您希望客户端不接收它无法处理的数据。您在这里至少有几个选择:
- 要求客户端在发送另一条消息之前主动响应已处理的消息。
专业人士:这是一个立竿见影的解决方案,因为服务器永远不会超过客户端可以处理的传输速率。
缺点: 这会增加网络协议的带宽开销和延迟。 ping 时间长的客户端会受到影响,即使它能够快速接收数据。
- 跟踪客户端似乎能够处理的数据速率,并减慢消息的具体化,使服务器不超过此速率。
Pro:此解决方案将始终保持客户端能够处理的最高传输速率。
缺点: 至少在最初,并且可能会间歇性地随着客户自身能力的变化而变化,这可能会暂时超出客户跟上的能力
- 使用 UDP,这将允许网络传输层丢弃客户端处理速度不够快的数据报。
专业人士:这个解决方案将整个问题委托给网络传输层,让您担心服务器和客户端的真实细节
缺点: UDP 本质上是不可靠的。除了处理丢失的数据报(在您的情况下这是一个好处),您还必须准备好处理乱序接收的数据报,以及不止一次接收到的单个数据报。
鉴于广泛陈述的问题,这是一个尽可能具体的答案。