Gabe
Gabe

Reputation: 971

c# multithreaded server - Generic client collection being a possible issue

I am developing a game emu in c# using async sockets. Currently, the program uses a List to store the clients.

If a client joins a room, a local list is created storing all the users from that specific room (I am using FindAll(x => x.room == this.room)). That list is needed because when a client changes rooms, the server must send a certain packet to announce all the other players in the room that a client joined.

Something like this:

var localist = Clients.FindAll(x=> x.room == this.room);
foreach(stateObj client_in_room in locallist)
{
    client_in_room.sendPacket(...); //what if the client_in_room disconnected in the meanwhile?
}

When a client disconnects, it (stateObj) gets removed from the original client list (and the client socket closes), and a client volatile boolean called ConnectionFired changes to false (it is meant to check if the user is still connected before doing socket operations like BeginSend, etc.). What if a client disconnects from room X while some other client joins a room X? It will still be in the local list for sure but will the ConnectionFired bool change its value? I guess not. It only affects the main/original list.

My concerns are that if that^ happens then the server could try send data to a closed socket (since the bool that checks for this, ConnectionFire, will not change its value when required).

To avoid this kind of stuff, should I avoid doing clones of the list, and use a for on the main list directly? (I initially did this locallist thing to avoid the collection was modified exception).

Upvotes: 1

Views: 169

Answers (1)

dan
dan

Reputation: 198

Yuo You seem to be asking two questions here

  1. You are concerned about managing a collection in a thread safe manner

  2. You are concerned about trying to send data over a socket when the other party is disconnected.

To answer your concerns given the limited information

  1. If you have multiple threads accessing your list then you need a thread safe implementation. You can roll one yourself using lock etc or use one of the new .NET ones. http://msdn.microsoft.com/en-us/library/dd997305.aspx Regarding you comments about "local" lists, the simple answer is do not make local copies unless you want to run the risk of having stale data. Use a thread safe list and also enumerate through it directly. If you use LINQ expressions then you can make complex queries without needing to make any copies of you collections.

  2. When sending data over socket then you ALWAYS need to handle the case when the other party has gone. If they have gone, then you must handle the error and decide if you want to retry, or move onto your next task. You simply cannot predict in advance when another party may die or if it will even tell you in a graceful manner (e.g "good bye"). So in a very simple solution wrap your sendPacket in some exccption handling / logging.

Upvotes: 1

Related Questions