TCP Games - Application Protocol

Let's first talk about how our clients and server are going to pass around messages/packets.  To make this more structured than last time, we will be using JSON, which will only contain plaintext.  Each JSON object will only have two fields, command and message.

  • command: this tells the client/server how the packet should be processed
  • message: this adds some extra context for the command.  It may be an empty string sometimes

 

We have only three simple commands for each type of packet:

  1. bye: this can be sent by either the server or the client.  It notifies the other end that the sender is disconnecting gracefully. 
    • If sent by the server to the client, the client should display the contained message and clean up its network resources
    • If sent by the client to the server, the server can choose what to do with the message (if there is one).  It should also clean up any resources associated with the client
       
  2. message: note that this is a command.  It just sends a plaintext message
    • If sent by the server to the client, the client should print out the contents of the message field
    • If sent by the client to the server, the server can chose to ignore it.  The client shouldn't be sending message packets anyways
       
  3. input:  requests some input
    • If sent by the server to the client, the client should ask the user for some input
      • the contents of the message field should be treated as a prompt for the user
    • If sent by the client to the server, this should only be in response to an input request
      • If this wasn't a response to a request, the server should just ignore the packet then

 

If you're a little confused, here's a diagram of how our apps will operate:

 

 

Packet class

Here is our Packet class.  ne sure to add it to both projects in your solution.  The main reason we have this is so we can access the data in a more C# like way.  We will be using Newtonsoft's Json.NET library for parsing.

 

 

How it will be sent over the network

Before we go and shove the Packet into the internet tubes there is a little pre-processing that needs to be done first:

  1. Call the ToJson() method on the Packet to get it as a string.  Then after that, encode it (in UTF-8) into a byte array
  2. Get how many bytes are in that first byte array, then encode that number as an unsigned 16 bit integer into a second byte array.  The resulting array should be exactly two bytes long
  3. Join those two arrays into a new one with the "length buffer," ahead of the "JSON buffer,"

That final byte array that we have is what will be sent over the network.  This way whoever receives a Packet knows how long it is.

 

You might be wondering why we have to do this.  Here's the thing, TcpClient.Available will report how many bytes have been received but not read yet, and only that.   There is the possibility that two Packets may have been received before our app has had a chance to read from the NetworkStream.  This poses the question of how we will pull out the data into two separate Packets.

Since we are using JSON, we could match first level curly brackets.  Instead, stuffing the length of the "true message," right before the actual message is a common technique that is used, and thus it's best that we practice that here.

 

I chose to use unsigned an unsigned 16 bit integer because it lets us have JSON strings that are almost 64 KB long; that's plenty of data for text based games.  We could use just an 8 bit unsigned integer too but that will only give us 255 bytes max, so our messages we send would have to be quite tiny.  

© 16BPP.net – Made using & love.
Back to Top of Page
This site uses cookies.