将TCP用于实时命令:Nagle算法会导致巨大的延迟,我该怎么办?
我正在编写一个套接字服务器和flash游戏客户端。游戏需要实时命令,如移动和转弯。服务器尽快将这些命令发送到客户机是很重要的,因为其他客户机将与移动/转向客户机大量失同步 这是Nagle算法引起的问题的一个示例: 注意:如果您想了解这些命令的含义,请参阅下面的命令表 第一个是我移动的船(向前移动+向右移动,向前移动已收到,但没有向右移动) 客户端发送命令:将TCP用于实时命令:Nagle算法会导致巨大的延迟,我该怎么办?,tcp,network-programming,client-server,network-protocols,real-time,Tcp,Network Programming,Client Server,Network Protocols,Real Time,我正在编写一个套接字服务器和flash游戏客户端。游戏需要实时命令,如移动和转弯。服务器尽快将这些命令发送到客户机是很重要的,因为其他客户机将与移动/转向客户机大量失同步 这是Nagle算法引起的问题的一个示例: 注意:如果您想了解这些命令的含义,请参阅下面的命令表 第一个是我移动的船(向前移动+向右移动,向前移动已收到,但没有向右移动) 客户端发送命令: 84796: Sending data: 2#4 84796: Sending data: 2#2 84904: Sending data:
84796: Sending data: 2#4
84796: Sending data: 2#2
84904: Sending data: 2#3
84904: Sending data: 2#0
86187: Sending data: 2#4
86188: Sending data: 2#2
86374: Sending data: 2#3
86404: Sending data: 2#0
79244: Raw receive: 3#3#4$
79244: New command: 3#3#4
79398: Raw receive: 3#3#2$3#3#3$3#3#0$
79399: New command: 3#3#2
79399: New command: 3#3#3
79399: New command: 3#3#0
80635: Raw receive: 3#3#4$
80635: New command: 3#3#4
80908: Raw receive: 3#3#2$3#3#3$3#3#0$
80908: New command: 3#3#2
80908: New command: 3#3#3
80908: New command: 3#3#0
接收命令的客户端:
84796: Sending data: 2#4
84796: Sending data: 2#2
84904: Sending data: 2#3
84904: Sending data: 2#0
86187: Sending data: 2#4
86188: Sending data: 2#2
86374: Sending data: 2#3
86404: Sending data: 2#0
79244: Raw receive: 3#3#4$
79244: New command: 3#3#4
79398: Raw receive: 3#3#2$3#3#3$3#3#0$
79399: New command: 3#3#2
79399: New command: 3#3#3
79399: New command: 3#3#0
80635: Raw receive: 3#3#4$
80635: New command: 3#3#4
80908: Raw receive: 3#3#2$3#3#3$3#3#0$
80908: New command: 3#3#2
80908: New command: 3#3#3
80908: New command: 3#3#0
“瞬间”是一个奇怪的术语,它并不是我想说的意思,
但在这里,似乎是上一个命令之后的时间量(以毫秒为单位)
84796: Sending data: 2#4
84796: Sending data: 2#2
84904: Sending data: 2#3
84904: Sending data: 2#0
86187: Sending data: 2#4
86188: Sending data: 2#2
86374: Sending data: 2#3
86404: Sending data: 2#0
79244: Raw receive: 3#3#4$
79244: New command: 3#3#4
79398: Raw receive: 3#3#2$3#3#3$3#3#0$
79399: New command: 3#3#2
79399: New command: 3#3#3
79399: New command: 3#3#0
80635: Raw receive: 3#3#4$
80635: New command: 3#3#4
80908: Raw receive: 3#3#2$3#3#3$3#3#0$
80908: New command: 3#3#2
80908: New command: 3#3#3
80908: New command: 3#3#0
客户端->服务器
服务器->客户端
因此,您可以看到,由于“Nagle”,这些命令完全不同步。这会导致其他客户端在接收开始移动命令的同时接收停止移动命令,从而导致该播放器根本不移动
这就是为什么我需要TCP服务器以尽可能快的速度实时发送这些命令。一个简单的解决方法是简单地禁用Nagle。然而,我有一点(注意,他关于tcp消息部分的建议是在我的系统中实现的,但与时间无关),并注意到人们绝对不建议禁用Nagle
我真的不应该因为这个原因禁用Nagle算法,而是应该寻找其他解决方案吗?为什么
提前谢谢。
-Tom您想使用TCP\u节点延迟来关闭该套接字的nagle算法。现代操作系统中有一些设置可以在系统范围内禁用它,这是不受欢迎的,但没有理由不使用一个需要低延迟的套接字
请注意,您的交换机、路由器、ISP的交换机。。。。等也可能唠叨他们的黑色小内脏。这些肮脏的小动物会读数据包,所以他们有时会随意重写
查看RTP(通过UDP运行)以获得更具网络生存能力的方法。如果需要尽可能快的速度,您应该使用UDP 但是,请注意,TCP提供交货和订单保证,而UDP不提供任何保证 这一点在这个应用程序中似乎非常重要,因此您必须在上面分层您自己的确认/重试命令排序机制 如果你想坚持使用TCP,TCP__;u NODELAY会有所帮助。随着游戏的发展,您可能最终需要TCP非常适合的数据流,而无需TCP_NODELAY
RFC1006规范化了通过TCP流发送数据包的机制。如果您的目标是让船只在每个人的屏幕上都做同样的事情,那么您必须发送位置更新。您不能仅仅因为客户A做了以下事情就认为:
- 左转
- 等待100毫秒
- 停止转动
- (我在位置X1,Y1,航向Z1)左转
- (我在位置X2,Y2,航向Z2)停止转向
这样客户端就会不断地重新同步。请注意,Windows不仅实现了Nagle,而且还实现了Nagle。这会给您在单个TCP消息上额外的200毫秒延迟。据我所知,除非通过注册表项(以及在某些情况下启用注册表项的热补丁),否则无法在Windows上更改此设置。我应该提供更多背景信息。我正在这么做,所以别担心。我在这篇文章中提出的主要问题已经解决了。谢谢。OP没有说他需要尽快完成。他只是说他希望立即发送数据,这是明显不同的。在所有其他条件相同的情况下,转向唠叨比直接跳到UDP要好得多。这让人困惑,两个人在一个线程中有相同的名字。唠叨算法,而不是“算术”。