使用 SFML 验证实时网络上发送的数据包

Verifying sent packets on real time network using SFML

我正在构建一个可联网的程序,它使用 SFML UDP 库在二维屏幕上传输图形更改。

我想 运行 关闭主机服务器上的所有处理,只向客户端发送图形更新和命令 return 值。

我想在数据发送到连接两端的屏幕之前做一个验证条件。我正在考虑将单个字节作为 0 或 1 发送,以表示成功接收数据并进行同步。

(见图)

    Server-------( updates )----->Client  
       |                             |  
  ( wait for )<---( 1 or 0 )-----Send Byte  
       |                             |  
    ( if 1 )                ( if byte received )  
       |                             |  
    Screen                        Screen  

来回 ping 似乎合乎逻辑,以确保在更新屏幕之前在两端验证数据,然后 运行 对同一事物进行另一次迭代(当然是无限期)。

我的问题是,使用 SFML,发送 1/0 是否有意义,或者它会自行验证,即。发送数据时带有 return 值?

此外,通过网络发送一个字节比做其他事情(比如尝试与时间同步)更慢吗?使用 FPS 是否有更好的方法来做到这一点?

关于 SFML 的答案可能是最好的。

如果要用 UDP 模拟 TCP,为什么不使用 TCP?

如果您坚持使用 UDP,因为性能可能很关键(即使您认为性能很关键,TCP 也可能会完成这项工作),您的客户端应该发送它的 commands/changes/data 并且仅在收到数据,从不费心发回布尔值(或单个位),因为有更好的方法来处理这个问题,这是对整个数据包的巨大浪费。

简单的方法

  1. 如果客户端从未收到请求的特定 return 值,只需在给定的时间阈值后向服务器重新发送请求并希望最好。
  2. 如果没有任何变化 client-side 并且服务器也没有任何变化,只需重新绘制屏幕(或等待客户端更改)
  3. 如果在一次或多次重发请求后服务器没有任何响应,请将问题通知客户端。 (连接丢失,或服务器错误)

在我所描述的内容中,服务器只需响应一次来自客户端的请求,然后就不用管了。

  1. 如果服务器从未收到请求(因此从不响应客户端),客户端无论如何都会发回其请求。
  2. 如果服务器响应在服务器和客户端之间丢失,客户端将在时间阈值后再次将其请求发送回服务器。

很难为您提供正确的解决方案,因为我们缺乏有关您要实现的项目的信息。

但假设这是一个游戏。

如果是游戏,简单的方法就是

在游戏中,您不会信任客户端,因此玩家执行的每个命令都会发送到服务器。服务器处理命令,进行所有计算并跟踪整个游戏的所有玩家。

然后,服务器return将新位置发送给客户端。客户端仅显示来自服务器的更改。例如,客户端从不在键盘输入上移动播放器。输入被简单地发送到服务器 as-is,客户端从服务器接收一个新位置,移动指定的图形,然后呈现到屏幕。

就是这样。

现实世界的方式

事实上,真实世界的游戏客户端会处理输入,它们会尝试插入更改 before/while 向服务器发送请求,然后根据接收到的数据进行调整。这给人一种没有延迟的错觉,即使网络通信不可避免地延迟也是如此。延迟仍然存在,因为数据包在连接不良或间歇性延迟时丢失,但插值仍然有帮助。

有了这个,你仍然不信任客户端,你只是在服务器响应之前猜测。

所有这些,是 TCP 还是 UDP?

这些策略与协议无关,因为您自己处理问题。

UDP

如果您要发送大量仅在发送时相关的数据,UDP 可以胜任。想想 video-conference 或语音聊天,当您丢失一个数据包时,再将其发回已经来不及了。

TCP

如果您要发送中等数量的信息,例如每秒仅发送 60 次位置信息,则接收顺序可能比带宽或延迟更重要,因此 TCP 可能是可行的方法。

不要重复自己

如果您要有一个单独的服务器应用程序,不要让它也显示在屏幕上,只需 运行 服务器机器上的另一个客户端,通过本地主机连接。