c# - 如何在 C# 中获取服务器和客户端之间的延迟?

标签 c# .net sockets client-server latency

我正在为我在 ActionScript 3 中编写的游戏引擎开发 C# 服务器应用程序。我正在使用权威服务器模型来防止作弊并确保公平游戏。到目前为止,一切正常:

当客户端开始移动时,它通知服务器并开始在本地渲染;然后,服务器告诉其他所有人客户端 X 已经开始移动,并提供详细信息以便他们也可以开始渲染。当客户端停止移动时,它会通知服务器,服务器根据客户端开始移动的时间和客户端呈现滴答延迟执行计算并回复每个人,以便他们可以使用正确的值进行更新。

问题是,当我在服务器计算中使用默认的 20 毫秒滴答延迟时,当客户端移动相当长的距离时,当它停止时会明显向前倾斜。如果我将延迟稍微增加到 22 毫秒,在我的本地网络上一切都运行得非常顺利,但在其他位置,倾斜仍然存在。经过一些试验后,我注意到所需的额外延迟与客户端和服务器之间的延迟密切相关。我什至将其归结为一个非常有效的公式:延迟 = 20 +(延迟/10)。

那么,我将如何继续获取特定客户端和服务器之间的延迟(我正在使用异步套接字)。 CPU 的工作量不能太大,以免服务器运行缓慢。另外,这真的是最好的方法吗?还是有更有效/更简单的方法来做到这一点?

最佳答案

抱歉,这不能直接回答您的问题,但一般来说,您不应该过分依赖测量延迟,因为它可能变化很大。不仅如此,您甚至不知道您测量的 ping 时间是否对称,这一点很重要。如果事实证明 20 毫秒的 ping 时间实际上是从服务器到客户端的 19 毫秒以及从客户端到服务器的 1 毫秒,那么应用 10 毫秒的延迟校正是没有意义的。应用程序术语中的延迟与网络术语中的延迟不同——您可能能够 ping 某台机器并在 20 毫秒内获得响应,但如果您正在联系该机器上每秒仅处理网络输入 50 次的服务器,那么您的响应将额外延迟 0 到 20 毫秒,而且变化相当不可预测。

这并不是说延迟测量在平滑预测中没有一席之地,但它不会解决您的问题,只是稍微清理一下。

从表面上看,这里的问题似乎是您在第一条消息中发送了信息,您用它来推断数据,直到收到最后一条消息。如果其他一切都保持不变,那么第一条消息中给出的移动向量乘以消息之间的时间将为服务器提供客户端大致现在所处的正确结束位置-(延迟/2)。但是,如果延迟发生任何变化,则消息之间的时间将会增加或缩短。客户端可能知道他移动了 10 个单位,但服务器模拟他移动了 9 或 11 个单位,然后才被告知将他快速恢复到 10 个单位。

对此的一般解决方案是不假设延迟将保持不变,而是发送周期性的位置更新,这允许服务器验证和纠正客户端的位置。现在只有 2 条消息,所有错误都会在第二条消息之后找到并更正。消息越多,错误就会分布到更多的样本点,从而实现更平滑、更不可见的校正。

但它永远不可能是完美的:它所需要的只是在最后一毫秒的移动中出现滞后峰值,并且服务器的表示会过冲。如果你根据过去的事件预测 future 的走势,你就无法解决这个问题,因为除了选择正确但迟到或不正确但及时的选择之外没有真正的选择,因为信息需要时间来传递。 (怪爱因斯坦。)

关于c# - 如何在 C# 中获取服务器和客户端之间的延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/770978/

相关文章:

c# - WCF:客户端配置中的契约(Contract) 'X' 与服务契约(Contract)中的名称不匹配

c# - 无需大量转换即可创建和初始化不同的子类型

c# - 非顺序列表绑定(bind)不起作用

asp.net - 我可以安全地删除临时 ASP.Net 文件夹的内容吗?

java - 从子线程访问父实例

c# - 关闭 View 会将 ViewModel 的属性设置为 null

c# - NoAutomaticTrigger 类型作业的连续 Azure WebJob 停止时的通知

c - 底层套接字编程

c# - .Net 中的零舍入错误类?

C# 套接字服务器 - 部署、启动、停止