Socket Server Example

Hello all!

I’m reposting this entry that I had originally posted in my After dev blog. Since I’ve begun rewriting After as a web app, all the code I’d written for it will be thrown out. But I still think it’s pretty cool information to share, so here it is. 🙂

—– Original Post from February 23, 2016 —–

For my first post on the topic of C# and UWP, I suppose it would be fitting to write about the first challenge I faced when developing After: How do I create a socket server?

I had experimented with socket servers previously in WPF applications, but I didn’t have very much experience with them. Also, UWP apps use a different library for sockets, and I’d never sent anything other than strings over them. So it was kind of intimidating at first. However, the API is very similar to WPF’s socket library, and after breaking it down and taking it one step at a time, it was a lot more simple than I had anticipated.

Just like WPF apps, stream sockets have a listener class that fires a connection received event upon connection requests. So I set up my StreamSocketListener like so. In this case, I used a static class and static methods for my socket server, but you can instantiate it any way you want.

So far, pretty straight-forward, but a few comments might be warranted. For event binding on static or persistent objects, I always remove before I add. I had an issue once with events getting bound multiple times, likely due to poor coding practices. 😀 Hey, I’m still learning! But since no exceptions are thrown by attempting to remove a binding that doesn’t exist, I don’t see any harm in doing so, and it ensures that there will always only be one binding.

VMS is the view model for the server. Current is a singleton instantiation of it. The Port property is bound two-way to the text box where the port number is entered. The SocketLookup collection will be used later to retrieve the sockets for individual connections based on their ID/username.

Now we have a server listening for connections. Here’s what happens with incoming connections.

I’ve removed the majority of what occurs here for security reasons, since sharing this information could assist someone in circumventing my security. This is where you want to perform any initial security checks (i.e. banned IPs, DoS protection, etc.). If everything checks out, I assign a GUID to the socket and send it back to the client so it’s aware of its own ID. I then pass the socket and its ID to ConnectionToClient, which is responsible for handling all communication from this point on. On the client side, the connection is getting passed to a respective ConnectionToServer class. 🙂

The ConnectToClient method handles the account authentication and assigns a username to the socket. We’ll skip that since it uses the same techniques as what follows, which is basically an infinite loop that will handle the rest of the incoming data from the socket for the remainder of its lifetime.

First, it waits for data to come in on the network stream. Everything I send over a stream socket is preceded by exactly 4 bytes, which is a UInt32 that lets the receiving data reader know how much data to read. There are other ways to handle the reading data from network streams, but this is the way I chose.

Everything that’s sent from server to client and back is serialized into XML, so it’s expecting the incoming data to be a string. It sends that string to the Utilities.Deserialize method, which will convert the string into an object. I’ll go over how the serialization works in my next post.

Next, we send that object to ReceiveDataFromClient for processing. Every object that’s sent over the network stream has a common interface. By checking the type of class being received, the receiver knows which method to call that will execute the logic necessary to process it. For example, if the data coming in is of type Message, there could be a ShowMessage method on it that will display the message according to its properties.

This loop repeats indefinitely until an error is encountered. The example above merely logs the player out, but you could also include advanced error handling depending on the situation, such as reconnection attempts, etc.

Well, that’s all for the socket server, I think! In later posts, I’ll talk about how the serialization works and how to construct your classes that will be used to send data over the network (also called Data Transfer Objects or DTOs).

Take care!

– Jared