Search code examples
csocketswinsock2

Can a single socket handle multiple concurrent requests?


Edit: My application is multi-threaded

Imagine I have a server,

int main()
{
   resolveAddrandPort(hostname, port); // Custom function
   
   SOCKET listening_socket = socket(/* args... */);   // Creates a socket.
   bind(listening_socket, /* args... */);             // Binds the socket to the address and port provided above.

   listen(listening_socket, default_backlog);         // Places the socket in a mode where it can accept any requests.

   add_handlers(10); // Custom function that adds 10 handlers which each run on different threads and can handle requests concurrently (using the same socket[=listening_socket]).

   while(is_recieving_requests)
   {
       SOCKET client_socket = accept(listening_socket, /* args... */);
       handle_request( // Custom function
            find_available_handler(), // Custom function that finds among the 10 handlers which of them is currently free and not handling any requests to handle this request.
            client_socket
       ); 

       clean_up(); // Custom function that cleans up after finishing with the request.
   }

   server_clean_up(); // Cleans up after the server.
}

I am using winsock to create the server,

In the documentation about listen says that you can provide a backlog determining how many requests can be pending.

Now this might be dumb, but I am assuming that a single socket cannot concurrently handle multiple request. If so, I think that I have to create multiple listening_sockets to be able to handle it concurrently.

Please correct me if I am wrong and I thank you for your patience.


Solution

  • Your question is a bit vague but I'll try to summarize. You can have a single listen socket to accept requests from incoming connections or messages (regarding UDP).

    single socket cannot concurrently handle multiple request

    The concurrently is what's throwing me off. The backlog implies you can have an x maximum number of requests pending until you either accept or drop them, then new requests will be allowed.

    In TCP, a single listen socket will be used to accept requests from connections. You can then distinguish each connection with its own socket.

    In UDP a single listen socket can be used to accept requests which are defined by their remote address. You can also send to many different connections using that remote address with a single socket.

    I think the ambiguity in your question lies about whether you can read requests from many sockets simultaneously in a single thread. In typical blocking I/O you can only read from one socket at a time. Which is why Non blocking sockets exist. This can let you loop through each socket and check if there's pending data. In which case the data can be retrieved.

    If you're thinking about running a thread per socket so you can read a request from each one (which many beginners to networking do because they learnt it from somewhere). And judging by your code it appears to be what you're doing. THIS IS A TERRIBLE IDEA! It might be an "OK" solution for ephemeral sockets (single HTTP requests) but not for long term connections. But I would not even use a thread per socket even for a single request. This can lead to vulnerabilities.