我正在写一套接字服务器和闪游戏的客户。游戏需要的真实时间的命令,例如移动和转向。重要的是对这些命令是由服务器发送到客户的尽可能的,因为其他客户将无desynchronise了很多运动/转向客户。

这是一个例子引起的问题的Nagle运算:

注意到:看到命令表以下如果您希望了解这些命令的意思。

第一个是船舶我搬(向前移动+右,前收到但未)

客户发送命令:

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

"瞬间"是一个陌生的术语,并不意味着什么,我想说的 但在这里,它似乎量的时间在毫秒之后,先前的命令

  1. 向前移动 发送的客户(下:0)时,收到客户B(下:0)

  2. 右转 发送的客户(下:0)时,收到客户B(下:155)

  3. 停止移动 发送的客户(下:108),收到的由客户B(下:0)

  4. 停止转动 发送的客户(下:0)时,收到客户B(下:0)

  5. 向前移动 发送的客户(下:1283),收到的由客户B(下:1236)

  6. 右转 发送的客户(下:1),收到的由客户B(下:273)

  7. 停止运动 发送的客户(下:186),收到的由客户B(下:0)

  8. 停止转动 发送的客户(下:30),收到的由客户B(下:0)

这是命令表相应的命令:

客户机->的服务器

2# (movement info)
0) now not turning
1) now turning left
2) now turning right
3) now not moving
4) now moving forward

服务器->的客户

3# (movement info)
[shipId]#
0) now not turning
1) now turning left
2) now turning right
3) now not moving
4) now moving forward

所以,你可以看到的是,该命令是完全desynched因为"Nagle".这会导致停止移动的命令将收到由其他客户同时作为开始的运动的命令,使得播放不动。

这就是为什么我需要这些命令可以送实时,尽可能快地由TCP服务器。一个简单的解决方法将是简单地禁止Nagle.但是,我有 用google搜索 (注意,他建议,关于tcp信息的部分是执行在我的系统,但没有时间)一位,并注意到,人们绝对不是建议禁用Nagle.

这是真的,我不应此项将不发送部份帧对于这个原因,而应寻找其他解决办法?为什么(没有)?

在此先感谢。-汤姆

有帮助吗?

解决方案

您希望使用TCP_NODELAY关闭该套接字的nagle算法。现代操作系统中有一些设置可以在系统范围内禁用它,并且 IS 不赞成,但没有理由你不应该使用你知道需要低延迟的套接字。

setsockopt(TCP_NODELAY)

其他提示

如果需要尽可能快,则应使用UDP。

但请注意,TCP提供传递命令的保证,而UDP则不提供。

这一点在这个应用程序中似乎是一个严重重要的点,所以你必须在顶层分层你自己的确认/重试命令排序机制。

如果你想坚持使用TCP,TCP__NODELAY会有所帮助。随着游戏的进步,您可能最终需要一个TCP数据流,TCP将非常适合没有TCP_NODELAY。

RFC1006规范了一种通过TCP流发送数据包的机制。

请注意,您的交换机,路由器,ISP的swithcgear ....等也可能都会将他们的黑色小胆刺出来。肮脏的小野兽可以读取数据包,因此它们会自由并重写它们。

查看RTP(通过UDP运行)以获得更多网络可用的方法。

如果你的目标是有船舶,结束了做同样的事情每个人都在屏幕上,你们要的位置发送更新。你不能假定只是因为客户一样:

  • 左转
  • 等等100毫秒
  • 停止转动

那个客户B会看到,完全相同的100毫秒的拖延。该Nagle的缓冲,只是使得这个更极端的-但是总是会有的抖动和变化延迟。

你真正需要的发送是这样的:

  • (我在位置X1,Y1题Z1)左转
  • (我在位置X2,Y2题Y2)停止转动

所以,客户不断resynchronising.

请注意,Windows实施延迟确认以及Nagle。这可以在单个TCP消息上额外延迟200ms。据我所知,除了通过注册表项(以及在某些情况下启用注册表项的hotpatch)之外,您无法在Windows上更改此内容。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top