Can a server handle multiple sockets in a single thread?

I am writing a test program that should emulate several connections between virtual machines, and it seems that the best way to do this is to use Unix domain sockets for various reasons. It doesn't really matter if I use SOCK_STREAM or SOCK_DGRAM, but it seems that SOCK_STREAM is simpler / easier for me to use.

My problem seems to be slightly behind the typical scenario. I want one client to communicate with the server through 4 different sockets. (I could have 4 clients with one socket each, but this difference should not matter.) Now what I emulate does not have multiple streams and receives an interrupt whenever a data packet is received on one of the "sockets". " Is there an easy way to emulate this using Unix sockets?

I believe that you first need to do socket() , bind() and listen() for all 4 sockets, and then do accept() for all 4 and do fcntl( fd, F_SETFF, FNDELAY ) for each of them to make them non-blocking, so that I can check each of them for data using read() circular way. Is there a way to make it controlled by interrupt or event-driven, so that my main loop only checks for data on the socket, if there is data? Or is it better to interview them all like that?

+4
source share
1 answer

Yes. Processing multiple connections is almost synonymous with "server", and they are often single-threaded - but please, not so:

check each of them for data with read () in circular mode

This will require, as you say, non-blocking sockets and some delay in order for your cyclic to become a system that kills the busy cycle.

The main problem is detailing the delay. You cannot make it too small, or the loop will still have too much CPU time when nothing happens. But what about when something happens and something has data coming in to multiple connections at the same time? Now your delay can lead to lag behind tish, leading to connection failures, etc.

This is simply not possible, and no one writes the server this way, although I'm sure someone would seriously think if they did not know about the library functions designed to solve this problem. Please note that networking is a platform-specific issue, so they are not actually part of the C standard (which is not related to sockets at all).

Functions select() , poll() and epoll() ; the last one is specific to Linux, and the other two are POSIX. The basic idea is that call blocks that wait until one or more of any number of active connections are ready to read or write. The expectation that the socket will be ready for writing only makes sense with NON_BLOCK sockets. However, you do not need to use NON_BLOCK, and select() locks are locked independently. Using NON_BLOCK on separate sockets makes the implementation more complicated, but increases the performance potential on a single streaming server - this is the idea of โ€‹โ€‹asynchronous servers (for example, nginx ), a paradigm that contrasts with the more traditional threaded synchronous model.

However, I would recommend that you do not use NON_BLOCK due to the additional complexity. When / if it will eventually be called, you will find out. You still don't need threads.

There are many, many, many examples and guidelines for using select() in particular.

+4
source

Source: https://habr.com/ru/post/1502490/


All Articles