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

2022-01-19 00:00:00 network-programming c++ frame-rate sfml

我正在构建一个可联网的程序,该程序使用 SFML UDP 库在 2D 屏幕上传输图形更改.

I am building a networkable program that transfers graphical changes on a 2D screen with SFML UDP libraries.

我想在主机服务器上运行接近所有的处理,并且只将图形更新和命令返回值发送给客户端.

I want to run close to all of the processing on the host server, and only send the graphic updates and command return values to the client.

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

I want to make a verify condition before the data is sent to the screens on both sides of the connection. I was thinking about sending a single byte as either 0 or 1 to represent successful reception of the data and to synchronize.

(见图表)

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

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

It seems logical to ping back and forth to make sure the data was verified on both ends before updating the screen and then subsequently running another iteration of the same thing (indefinitely of course).

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

My question is, using SFML, is there a point in sending the 1/0, or will it verify on its own, ie. with a return value when the data is sent?

另外,通过网络发送一个字节而不是执行其他操作(例如尝试与时间同步)是否会更慢?是否有更好的方法来使用 FPS 做到这一点?

Also, is it slower to send that one byte over the network rather than doing something else, like trying to sync against time? Is there perhaps a better way to do this with FPS?

SFML 方面的答案可能是最好的.

Answers in terms of SFML will probably be best.

推荐答案

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

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

If you're going to simulate TCP with UDP, why not use TCP?

If you're adamant on using UDP as performance is maybe critical (and even if you think performance is critical, TCP will probably do the job), your client should send its commands/changes/data and only react on received data and never bother sending back a boolean (or single bit) as there are better ways to deal with this and it's a big waste of a whole packet.

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

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

In what I'm describing, the server only has to respond to requests from a client once and then forget about it.

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

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

It's hard to give you the right solution as we lack information on the project you're trying to achieve.

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

But let's say it's a game.

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

In a game, you wouldn't trust the client, so every command the player does is sent to the server. The server handles the command, does all the calculation and tracks all players for the whole game.

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

Then, the server returns the new position to the client. The client only displays changes coming from the server. For example, the client never moves the player on a keyboard input. The input is simply sent to the server as-is and the client receives a new position from the server, moves the designated graphics, then renders to the screen.

就是这样.

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

In fact, real world game clients handle inputs and they try to interpolate changes before/while sending requests to the server and then they adjust from the received data. This gives the illusion of absence of lag, even with the inevitable delay from network communications. Lag still exists because packets get lost on poor connections or intermittent latency, but interpolation still helps.

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

With this, you still don't trust the client, you're just guessing before the server responds.

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

The strategies are protocol agnostic, as you're handling the problems yourself.

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

If you're going to send a lot of data that is relevant only for the time it is sent, UDP will do the job. Think video-conference or voice chat, when you lose a packet, it's already too late to send it back.

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

If you're going to send moderate number of informations, like only the position 60 times a second, maybe the order of reception is more important than bandwidth or latency, so TCP might be the way to go.

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

If you're going to have a separate server application, don't make it also display to the screen, just run another client on the server machine, connected via localhost.

相关文章