2

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.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
dunworray
  • 49
  • 10
  • Ping does not tell server anything if updates are received or not by clients. I'm confused. – Ace Caserya Apr 27 '15 at 01:54
  • Sorry, by 'ping' I mean sending a single byte of data as either 1 or 0 to represent successful reception of the data on one end. – dunworray Apr 27 '15 at 02:36
  • "to do this with FPS", what do you mean with FPS? Because you tag the question with FPS as Frames per second, but you seem to be asking for First Person Shooter? Is that what you meant? – Emile Bergeron Apr 28 '15 at 00:50
  • 1
    The graphical changes need to be real time, as in fps (frames per second). I figured the tag would be relevant. – dunworray Apr 29 '15 at 23:58
  • Yes, it is in that case. It's the question, the part "with FPS" sounds weird. I would've asked "Is there a better way to do this with performance in mind?" or to maximize FPS, but still, FPS is sort of irrelevant to network performances as both are normally separate responsibilities for a client app. – Emile Bergeron Apr 30 '15 at 16:50

1 Answers1

4

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.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • +1 for a thorough answer. What I am specifically doing is an extremely simplified, real-time strategy game. The graphics themselves will all be 2d circles of various colors. The only necessary physics will be circle collision which is also fairly easy. The commands will all be key based, so I will have to regularly scan the buffer. The commands themselves will probably be represented by the single binary number 1-10, or 1-20 at the most. – dunworray Apr 29 '15 at 23:15
  • I am more concerned about creating an efficient, stable networking algorithm than an effective game. One other possibility I want to account for is multiple players, up to 8 say, on the same server. Is tcp still the best option? I remember reading something about socket controllers that could work. I will also be using dynamic memory and AI processes. – dunworray Apr 29 '15 at 23:17
  • I now understand what you're trying to achieve but I think the question is too broad for stack overflow. It isn't a question about a code snippet or a bug, you need conceptual help with real-time networking, which is not the target kind of questions stack overflow is seeking. The thing to remember though, is that you don't need to send back a confirmation to the server. Without thinking much, I would just make the server send the updated positions to each player every game tick, and the client only sending their commands. – Emile Bergeron Apr 30 '15 at 16:54
  • 1
    Fair enough... I'll just do that and play around with it I guess. – dunworray Apr 30 '15 at 17:30