【问题标题】:Verifying sent packets on real time network using SFML使用 SFML 在实时网络上验证发送的数据包
【发布时间】:2015-07-05 07:13:17
【问题描述】:

我正在构建一个可联网的程序,该程序使用 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 方面的答案可能是最好的。

【问题讨论】:

  • Ping 不会告诉服务器任何客户端是否收到更新。我很困惑。
  • 对不起,我所说的“ping”是指发送一个字节的数据作为 1 或 0,以表示在一端成功接收数据。
  • "用 FPS 来做这个",你对 FPS 是什么意思?因为您将 FPS 标记为每秒帧数,但您似乎要求的是第一人称射击游戏?你是这个意思吗?
  • 图形变化必须是实时的,如 fps(每秒帧数)。我认为标签是相关的。
  • 是的,就是这样。这是个问题,“带有 FPS”的部分听起来很奇怪。我会问“考虑到性能,有没有更好的方法来做到这一点?”或最大化 FPS,但 FPS 仍然与网络性能无关​​,因为两者通常是客户端应用程序的独立职责。

标签: c++ network-programming sfml frame-rate


【解决方案1】:

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

如果您坚持使用 UDP,因为性能可能很关键(即使您认为性能很关键,TCP 也可能会完成这项工作),您的客户端应该发送它的命令/更改/数据,并且只对接收到的数据做出反应并且永远不要费心发回布尔值(或单个位),因为有更好的方法来处理这个问题,这会浪费整个数据包。

简单的方法

  1. 如果客户端从未收到请求的特定返回值,只需在给定时间阈值后将请求重新发送到服务器并希望最好。
  2. 如果客户端没有任何变化并且服务器没有任何内容,只需重绘屏幕(或等待客户端更改)
  3. 如果在一个或多个重发请求后服务器没有任何消息,请通知客户端该问题。 (连接丢失,或服务器错误)

在我的描述中,服务器只需要响应一次来自客户端的请求,然后就忘了它。

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

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

但是让我们说这是一个游戏。

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

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

然后,服务器将新位置返回给客户端。客户端仅显示来自服务器的更改。例如,客户端永远不会在键盘输入上移动玩家。输入只是按原样发送到服务器,客户端从服务器接收一个新位置,移动指定的图形,然后渲染到屏幕上。

就是这样。

现实世界的方式

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

这样,您仍然不信任客户端,您只是在服务器响应之前猜测。

那么,TCP 还是 UDP?

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

UDP

如果您要发送大量仅与发送时间相关的数据,那么 UDP 就可以完成这项工作。想想视频会议或语音聊天,当您丢失一个数据包时,再发回已经太迟了。

TCP

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

不要重复自己

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

【讨论】:

  • +1 以获得详尽的答案。我专门做的是一个极其简化的即时战略游戏。图形本身都是各种颜色的二维圆圈。唯一必要的物理是圆碰撞,这也很容易。这些命令都是基于键的,所以我必须定期扫描缓冲区。命令本身可能由单个二进制数 1-10 或最多 1-20 表示。
  • 我更关心创建一个高效、稳定的网络算法,而不是一个有效的游戏。我要考虑的另一种可能性是同一服务器上的多个玩家,最多 8 个。 tcp 仍然是最佳选择吗?我记得读过一些关于可以工作的套接字控制器的东西。我还将使用动态内存和 AI 进程。
  • 我现在了解您要实现的目标,但我认为这个问题对于堆栈溢出来说太宽泛了。这不是关于代码 sn-p 或错误的问题,您需要实时网络的概念帮助,这不是堆栈溢出所寻求的目标类型问题。不过要记住的是,您不需要向服务器发回确认信息。不用多想,我只是让服务器在每个游戏周期向每个玩家发送更新的位置,而客户端只发送他们的命令。
  • 很公平......我想我会这样做并玩弄它。
猜你喜欢
  • 2018-08-15
  • 1970-01-01
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 2020-06-06
相关资源
最近更新 更多