我正在构建一个可通过SFML UDP库在2D屏幕上传输图形更改的可联网程序。
我希望接近主机服务器上的所有处理,并且只将图形更新和命令返回值发送到客户端。
我希望在将数据发送到连接两侧的屏幕之前进行验证。我正在考虑将单个字节作为0或1发送,以表示成功接收数据并进行同步。
(见图)
Server-------( updates )----->Client
| |
( wait for )<---( 1 or 0 )-----Send Byte
| |
( if 1 ) ( if byte received )
| |
Screen Screen
在更新屏幕之前来回ping以确保数据在两端都经过验证似乎合乎逻辑,然后再运行同一事物的另一次迭代(无限期)。
我的问题是,使用SFML,发送1/0是否有意义,或者它会自行验证,即。发送数据时返回值?
此外,通过网络发送一个字节而不是做其他事情比较慢,比如尝试与时间同步?使用FPS可能有更好的方法吗?
SFML方面的答案可能是最好的。
答案 0 :(得分:3)
如果您坚持使用UDP,因为性能可能至关重要(即使您认为性能至关重要,TCP可能会完成这项工作),您的客户端应发送其命令/更改/数据并仅对其做出反应收到数据并且从不打扰发回布尔值(或单个位),因为有更好的方法可以处理这个问题,而且它会浪费整个数据包。
在我所描述的内容中,服务器只需响应客户端的请求一次,然后忘记它。
由于我们缺乏您正在尝试实现的项目的信息,因此很难为您提供正确的解决方案。
但是,让我们说这是一场比赛。
在游戏中,您不会信任客户端,因此玩家所做的每个命令都会发送到服务器。服务器处理命令,完成所有计算并跟踪整个游戏的所有玩家。
然后,服务器将新位置返回给客户端。客户端仅显示来自服务器的更改。例如,客户端从不在键盘输入上移动播放器。输入只是按原样发送到服务器,客户端从服务器接收新位置,移动指定的图形,然后渲染到屏幕。
那就是它。
事实上,现实世界的游戏客户端处理输入,他们尝试在向服务器发送请求之前/同时插入更改,然后根据接收的数据进行调整。这给人一种没有滞后的错觉,即使网络通信不可避免地存在延迟。滞后仍然存在,因为数据包在连接不良或间歇性延迟时丢失,但插值仍有帮助。
有了这个,你仍然不信任客户,你只是在服务器响应之前猜测。
策略与协议无关,因为您自己处理问题。
如果您要发送大量仅与发送时间相关的数据,UDP将完成这项工作。想想视频会议或语音聊天,当你丢失一个数据包时,发送它已经太晚了。
如果您要发送中等数量的信息,例如每秒60次的位置,可能接收顺序比带宽或延迟更重要,因此TCP可能是最佳选择。
如果您要拥有单独的服务器应用程序,请不要让它显示在屏幕上,只需在服务器上运行另一个客户端,通过localhost连接。