.NET's async network security?

Started by
12 comments, last by Sirisian 15 years, 10 months ago
I've made an async multiclient server on C#, and I was having quiet a few problems dealing with received packets (packet ids getting mixed up with other packet ids). I was wondering if when making an async multi-client server I still need to implement thread security, or is this already taken care of with .NET's networking async methods?
Advertisement
You still need to build proper thread safety in to your application. For instance, when a new connection callback is called for BeginAccept(), if you want to add that Socket to a list, or pass it to a manage somewhere, you need to make sure that the add or the call to the manager are thread safe.
Like Gnome said, callbacks can come on any thread. Currently what I do is for async:

* Accept: Simply perform all the accepting on the callback thread since its all already thread safe since I'm just accepting the connection, nothing fancy.
* Send: When I send, I check if a send is already being performed. If so, I will throw the data in a Queue<>. If not, I begin the send. When a send finishes, if there is items in the queue, I simply dequeue as much as possible and send it.
* Recv: Received data is placed in a buffer to fix fragmented data. When a complete message is received, it is forwarded to a receive queue which I call once per frame. I have a method that will lock the queue, return all the messages received, clear the receive queue, then unlock it.

Nothing fancy or at all difficult. But starting to think in a multithreading mindset can be a bit of a challenge at first if you have never done so before.
NetGore - Open source multiplayer RPG engine
Hmm, so if I just pass the received data to a queue on the receive callback I wouldn't have to worry about handling the data on each thread and making each thread safe?
The queue itself needs to be thread safe (which can be done simply using lock).
If only one thread reads from the queue, then the processing of data doesn't need to be thread safe.
enum Bool { True, False, FileNotFound };
Oh okay. What I was thinking was just pass all incoming data to a global queue, and handle the whole queue on a separate thread (one single thread) to avoid complications. This would work wouldn't it?
You do not want to handle data asynchronously from the main game loop. You will end up with so many errors and so many locks that your program will die. Process the messages at the start of the update function or something. I process messages immediately when I get them and set update variables (setting the old values equal to the update variables at the beginning of a server tick). Anything that can't be processed is sent to specialized queues to handle it.

Remember 2 threads should not be accessing the same data. If you have to access a lot of the same data between two threads you might have a problem.
Keep in mind that you can use the System.Threading namespace, which includes stuff like System.Threading.Thread.CurrentThread.ManagedThreadId, which will let you check what thread you are currently using. I'd recommend using this if you do not have much experience with threads. Simply grab the ID of your main thread at initialization, then check that value against places you suspect could be using a different thread. Debug.Assert() can be useful here, or even just Debug.Print() and printing out the thread ID and manually checking for thread changes.
NetGore - Open source multiplayer RPG engine
Spodi outlined a good async networking pattern, very similar to one that I use myself, at least in C/C++. .Net has some interesting new async socket APIs that may warrant a rethink of of how to perform async networking. But regardless of how you go about receiving data from sockets, you will need to accumulate the bytes received in order to reassemble messages before dispatching them to the application. In other words, each socket should have its own accumulation buffer where incoming bytes are stored up until you have a whole message, then you can dispatch it to the app or queue it in a place the app can grab it later from its own thread.
I understand the main idea now, I just need to know some site where I could read about how the threading behind these async. networking functions for C# work.

Anyone got any good links :P?

This topic is closed to new replies.

Advertisement