views:

400

answers:

7

Hi,

As there are serveral ways of connecting multiclients to the server such as: fork, select, threads, etc. I would be glad if you could describe which is better to connect multiple clients to the server?

Thanks for you time and reply?

+4  A: 

Design some heartbeat loop, which will go over all of your sockets and respond to their respective events.

I recommend the server to be passive (clients will connect to it, instead of server connecting to the clients) as it is normally done on the web. Therefore, it will also have a listener socket.

Pavel Radzivilovsky
Heartbeat loop is a bad idea. As it implies a forced sleep between checks (maybe you have something else in mind in which case ignore this). There is already an API that waits for data on a set of sockets. Check out 'http://linux.die.net/man/2/select'
Martin York
And epoll on Linux, kqueue on BSDs/MacOSX, etc. :)
Nikolai N Fetissov
@martin, you wait on a set of sockets, but then you go over all list and see which got events.
Pavel Radzivilovsky
this is out of the topic. It is not about socket , but about handling multiple clients
make
+1  A: 

I know in C that fd_select offered this polling of sockets ability. Not sure, but i'm guessing that C# has a much nicer way of doing it.

Chris
thanks! could you please explain what do you mean by << polling of sockets ability ..
make
+1  A: 

One simple advice, avoid use fork as it create a heavy weight process, use threads instead that are much more lighter and shares the same memory space of the processes the created then.

Andres
It depends on OS. On UNIX, fork() and processes are efficient. Also address space shared between threads can cause very difficult to produce bugs.To sum up, both processes and threads have pros and cons.
el.pescado
thanks ! I know fork() is not supported on windows efficiently
make
+2  A: 

There are at least two options.

  • Create a listen socket.
  • Wait for a connection.
  • Spawn a thread to handle the connection.

or

  • Create a listen socket and wait on it with select().
  • If the listen socket fd becomes active, make a new connection and add the new fd to the select call.
  • If a connection fd becomes active, handle it.

If you understand threads, the first alternative might be a cleaner approach. The second approach needs some fd management (e.g. listen or connection), but can be done in a single thread.

what do you mean by this <<the first alternative might be a cleaner approach>>? can you explain pls?

If you understand threads and synchronization between threads, the first approach can be simpler because you can use normal blocking reads and writes to the connection socket.

The second approach requires that you use non-blocking reads/writes and handle partial data packets if you want to be able to handle all the clients simultaneously.

Richard Pennington
I understand thread and work with them on different OSs. Sorry I think you are out of the topic ... the question is not about socket, but is about connecting multiple clients to the server
make
Sorry, aybe I didn't make myself clear. I was describing two ways to have a server deal with multiple clients. I've used them both in the past.
Richard Pennington
what do you mean by this <<the first alternative might be a cleaner approach>>? can you explain pls?
make
+1  A: 

if your program is running on windows. Avoid threads and processes completely and use the asynchronous model of socket programming. It's by far the most efficient (and easiest way) to do network communications.

Toad
Thanks! Could you pls explain how to asynchronous sockets on windows and why threads are useless ...
make
+4  A: 

Take a look at the C10K page for a great overview and comparison of I/O frameworks and strategies.

Nikolai N Fetissov
thanks for link. it is interesting
make
Excellent webpage!
Steve Emmerson
+1  A: 

If you're using windows then the most efficient way to handle lots of clients is to build your server around asynchronous I/O and I/O completion ports. These allow you to service lots (10's of thousands) of clients with a small number (4?) threads in an efficient manner.

Some people find the asynchronous nature of the I/O completion port model to be a little difficult to understand but I have a free C++ source code framework that you could download from here to get you started. If you're using managed code then all of the asynchronous socket APIs in the .Net framework use I/O completion ports 'under the hood'.

The I/O completion port model scales well because it's an operating system primitive that was built from the ground up to be efficient; it knows if the threads associated with it are running or waiting and so can manage the number of threads that it allows to process 'completions' at the same time. It also uses the threads in a fifo order so that if there is little work to do then there are fewer wasted context switches as only the minimum number of threads will be used (rather than scheduling work items across all threads and causing all of their stacks to remain paged into memory). In contrast your own thread pool must be less efficient as you don't have the same level of knowledge of the threads as the IOCP has. Select often suffers from a limitation on the number of sockets that it can support which means that for true scalability you need to build some complex code on top of your select to be able to manage more than this number of clients. Using a thread per connection model is much less efficient as not only are new threads are started and stopped regularly but you have less ability to control the number of threads in the process at any one time - threads are relatively heavy-weight resources when you factor in their stack space, etc. Once you have more threads than CPU cores you will be losing time in context switches (which IOCP often avoids completely). Finally forking a new process per connection is even more heavy-weight than the thread per connection model and personally I don't see any reason to consider this a valid option on a modern OS.

Len Holgate
Thanks a lot for the reply
make