Reputation: 3563
I develop the server in C# and have a question:
Let's say I have the List <Socket>
, it have 20 objects, from the first object (socket) comes a message that I must:
or
Everything works correctly, if it is currently work one thread with List <Socket>
.
But if to List <Socket>
suddenly turn 20 threads simultaneously (message arrived from everyone), which not only pass on the List and send a message, but also on the basis of the contents of the messages can close the socket and remove it from the List, then I do not know how to create atomic access and not lose productivity.
String targetIp, msg;
lock(socketListMutex)
{
for(int i = 0; i < listSocket.Count; ++i)
{
if(listSocket.elementAt(i).targetIp == targetIp)
{
listSocket.sendTo(msg);
break;
}
}
}
Edit 1:
What can happen:
Upvotes: 2
Views: 91
Reputation: 61716
The following is based on my understanding of your question, while I'm not quite sure I understood it correctly.
A solution could be as simple as making a copy of the list of sockets, before processing it:
Socket[] sockets;
lock (socketListMutex)
sockets = listSocket.ToArray();
foreach (socket in sockets)
{
// check the state of each socket object
// and send a message if needed
}
Your requirements don't mention the situation when a new message arrive (possibly on a different socket) before the previous one has been fully processed. In this case, some additional logic would be required to preserve the order of the messages, like queuing.
On a side note, I don't think you need additional threads. Use asynchronous APIs instead:
foreach (socket in sockets)
{
// send a message to each socket
await Task.Factory.FromAsync(
(asyncCallback, state) =>
socket.BeginSend(buffer, offset, size, socketFlags, asyncCallback, state),
(asyncResult) =>
request.EndSend(asyncResult));
}
More on asynchronous socket operations:
Some thoughts about the threading model of a TCP server app:
https://stackoverflow.com/a/21018042/1768303
Upvotes: 1