5
votes

I need to write a server which accepts connections from multiple client machines, maintains track of connected clients and sends individual clients data as necessary. Sometimes, all clients may be contacted at once with the same message, other times, it may be one individual client or a group of clients.

Since I need confirmation that the clients received the information and don't want to build an ACK structure for a UDP connection, I decided to use a TCP streaming method. However, I've been struggling to understand how to maintain multiple connections and keep them idle.

I seem to have three options. Use a fork for each incoming connection to create a separate child process, use pthread_create to create an entire new thread for each process, or use select() to wait on all open socket IDs for a connection.

Recommendations as to how to attack this? I've begun working with pthreads but since performance will likely not be an issue, multicore processing is not necessary and perhaps there is a simpler way.

2
As a note, I'm working in C / C++BSchlinker
I should also mention, the number of connections to this system are static. This is not a public facing machine (connections will not change over time -- i.e, I don't see performance issues being a problem).BSchlinker
Personally, I would multiplex using select(), or preferably kqueue() if running on mac or bsd. Either of the three options would work, however, and the pthread/fork options are super easy to implement if your server is going to have a low client count and low active client contention.Jason Coco
And in the case that no clients were communicating with the server? (As in, all communication comes from the server to the client). What would be the best option then?BSchlinker
As a note, there is no language called C / C++. In which language are you working? C++ as tagged?Johnsyweb

2 Answers

5
votes

Child processes are not nice, because you just move the goalpost. You will need to make your child processes communicate between each other, then you are back to the same problem.

It is possible to use threads, but you will have other problems if your threads keep blocking on socket receive.

select() (or poll() on newer (POSIX) Unixes) is still the best solution. You tell either select() or poll() which sockets or descriptors you want to monitor for events (probably just input (read) events is enough for you), then you do the read only on that socket or descriptor that was flagged by select()/poll(). It is guaranteed that recv() will not block.

4
votes

Read the C10K page for whole bunch of options. Then read the High Performance Server Architecture article. These will answer lots of questions for you.

I would go with the third option. For that look into epoll(4) and/or kqueue(2) facilities for modern performant select/poll replacements.