Arrrr Arrrr - 25 days ago 11
C# Question

Creating a socket that can serve concurrent requests simultaneously

Assuming the following code:

Task.Run(()=>{
while(true){
Socket connection = socket.Accept(); // Problem
Task.Run(()=> { //Receive from and Send to connection } )
}
})


Although it is capable of serving connections in a multi-threaded way, all requests are served one after another and not in a fully concurrent way since the
socket.Accept()
is in the while loop. On the other hand, it cannot be moved into the inner task since it that case, an infinite (very large and unknown) number of
accept()
will be created.

What is the proper solution for this problem?

Example:

Connection A -- Accepted at 3:30:00:00 PM
Connection B -- Accepted at 3:30:00:00 PM
Instead of
Connection A -- Accepted at 3:30:00:00 PM
Connection B -- Accepted at 3:30:00:50 PM

Answer Source

I think there may be a couple of things going on here. Unfortunately, we don't get to see how you are using the socket object that gets returned by the accept method - and there may be some pitfalls there which can cause a delay - but in general, it is not possible to accept connections in strict parallel.

According to the documentation,

Accept synchronously extracts the first pending connection request from the connection request queue of the listening socket, and then creates and returns a new Socket.

So, .NET keeps (accesses) a queue of pending requests from the underlying OS (and important to note that this queue length is limited by the OS). Based on how TCP/IP works, only one client can be served at a time on a single socket. So, what happens is that one client connects, you call accept and a new TCP socket on a different (usually high numerical value) port is created for that client, which is returned by the accept method. This necessarily must happen in a serial fashion. The only way to initially connect multiple clients in parallel is to have multiple listening ports.