[null, null, {"document_url": "https://16bpp.net/tutorials/csharp-networking/07b", "unformatted_src": "https://storage.googleapis.com/sixteenbpp/tutorials/images/udp-pong-handshake.png", "src": "https://storage.googleapis.com/sixteenbpp/tutorials/images/udp-pong-handshake.png", "formatted_filename": "udp pong handshake", "alt_text": "UDP Pong Handshake", "rendered_width": 1000, "rendered_height": 656}, null, null]
UDP Pong - Protocol Design 
There's a lot more we have to do here than in the UDP File Transfer app.  By design UDP is connectionless, but the problem is that we need to have our clients to be able to establish a connection, maintain it, transfer data in between, and then quit when they want.  We'll be implementing these things ourselves.

Basic Packet Structure

The first four bytes of each packet will denote its PacketType.  Instead of encoding some ASCII bytes like we did with the File Transfer example we'll be using 32 bit unsigned integers (4 bytes).  The next eight bytes will be a Timestamp encoded in a signed 64 bit integer (8 bytes).  After that will be the Payload, it's just an array of bytes.  It can be empty or it might have something to it.  That all depends on the PacketType.  So at minimum all Packets will be 12 bytes long.

Types of Packets

Here is what each PacketType is, with a description:

Connection Establishment

This is our version of the TCP Three-Way Handshake.  The Client will send a RequestJoin to the Server.  The Server will respond with an AcceptJoin message; it is the only one that contains data (an unsigned 32 bit integer that denotes the Client's Paddle).  Then the Client will need to respond with the AcceptJoinAck.  Here is a diagram of the handshake: Maintaining the Connection

This is pretty simple, the client will send Heartbeat messages and the server will send back HeartbeatAck messages in response.  The Client and Server will also record the times they got them and use it to determine if a connection has dropped or not.  The heartbeat timeout value will be 20 seconds.  These are sent after a connection has been established, while waiting for a GameStart/GameStartAck, and while the game is being played.

Game Start

The Server will not start the game until two Clients are connected.  Once that criteria has been met, it will send out the GameStart messages.  The Clients will both need to respond with a GameStartAck before the Server will deliver any GameState messages.

In Game

A few times per second both the Clients and the Server will send each other info about their current state.  The Client only needs to send PaddlePosition Packets; it contains one floating point number that is the Paddle's Y position.  The Server will send a GameState Packet to both Clients.  It will contain the Paddle & Ball positions as well as the scores (see the diagram below for the data layout).  Periodically the Server will send a PlaySoundEffect message.  This will tell the Client it should play a sound effect.  The name of the sound effect is encoded as a UTF-8 string.

Check the code for Packet.cs for details, specifically the classes GameStatePacket, PaddlePositionPacket, and PlaySoundEffect.  They will show you how the data is laid out.

Ending the Connection

At any time a Client or Server could send a Bye.  This simply tells the other that the connection is over.  If a Client sends it to the Server while in the middle of a game, the Server then needs to notify the other client the game is over.  When the Server shuts down, it should send a Bye message to all connected Clients.