首先,我想为我糟糕的英语道歉:) 昨天我用Winsock和Allegro5用C ++编写了我的第一个多人游戏(Pong)。该游戏包含一个服务器,适用于所有玩家和客户。
每个帧(FPS = 60)客户端将他们的mouse_y坐标发送到服务器,服务器分别将它们传递给对手的客户端。当我在连接到服务器的2台计算机上玩游戏时,在其中一台服务器上运行,通过本地网络运行完美,对手的拨片移动顺畅。但是当我通过我的外部IP地址进行同样的连接时,对手的球拍是滞后的,这会破坏比赛,因为它的客户端会检查球是否击中了对手的球拍。因此,同步被破坏,每当我移动一个球拍在另一台计算机上反弹球时它会滞后并且没有及时制造,从而为对手得分......但这不是落后的比赛。我的球拍和球正在顺利移动。问题只出在对手的桨上。
我是网络编程的新手,因为我只读过Beej's Guide to Network Programming。 我使用TCP套接字发送paddles的()和recv()坐标以及select()函数来轮询套接字以获取数据。
我没有一个想法可能是什么原因。
TL; DR:当我通过外部IP连接时,对手的拨片滞后,但是当我通过本地IP连接时,它不会。
答案 0 :(得分:2)
嗯,这是完全预期的行为,由光速强加(等等)。通过互联网发送的数据包只需要一段时间才能到达:
$ ping stackoverflow.com
PING stackoverflow.com (198.252.206.16) 56(84) bytes of data.
64 bytes from stackoverflow.com (198.252.206.16): icmp_req=1 ttl=53 time=85.1 ms
这告诉我从我的机器到stackoverflow.com的RTT(往返时间)是85毫秒,这对网站来说很好,但足以导致实时游戏中的明显延迟。
这是坏消息。更糟糕的是,这是一个非常难以解决的问题。
专业的实时多人游戏使用了一些技巧来减少延迟。例如,他们会跟踪每个客户端的延迟,并尝试“预测”播放器在当前时间点的位置,即使这些数据包尚未到达。但是当然,如果数据包到达并且预测结果是错误的,这将导致玩家突然“跳”到正确的位置。为了解决这个问题,他们在预测位置和最后一个位置之间应用了一些平滑处理。如果做得好,就会产生实时运动的幻觉。
另一个问题是你不能仅仅在客户端上做你的游戏逻辑,因为每个客户对世界的看法都略有不同。让客户做预测是可以的,但是服务器应该掌握桨是否击球。
答案 1 :(得分:2)
延伸托马斯所说的话。我会给你一些更实际的答案。
如果您坚持使用TCP,请执行以下操作。
降低 TCPAckFrequency 的值。
禁用 nagle的算法,因为您的请求规模较小。通过将 TCPNoDelay 设置为1来实现。
缓解两点之间的移动。
包装其余部分时发送的数据较少。
将收到的数据包投射到结构中。
请勿使用select
。在50个左右的连接后,您会注意到huge
性能损失。分别对Windows / Linux使用epoll
或IOCP
。