Verifying sent packets on real time network using

2019-02-26 06:02发布

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.

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.

(see diagram)

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

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).

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?

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?

Answers in terms of SFML will probably be best.

1条回答
老娘就宠你
2楼-- · 2019-02-26 06:17

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.

The simple way

  1. If the client never receives a particular return value for a request, just resend the request to the server after a given time threshold and hope for the best.
  2. If nothing changes client-side and nothing is coming from the server, just redraw the screen (or just wait for a client change)
  3. If nothing comes from the server after one or more resent requests, inform the client of the problem. (Connectivity lost, or server error)

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

  1. If the server never receives the request (and therefore never respond to the client), the client will send back its request anyway.
  2. If the server response is lost between the server and the client, the client will, again, send its request back to the server after the time threshold.

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.

If it's a game, the simple way would be

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.

That's it.

The real world way

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.

So with all this, TCP or UDP?

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.

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.

And don't repeat yourself

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.

查看更多
登录 后发表回答