Client Server multiple connections in C
Asked Answered
B

3

5

I am trying to reason about how a simple server implemented in C with sockets can handle concurrent clients. Let's say a simple server waits for a client to connect and then read a message sent from the client. read() is a blocking function so the server will block until a client writes to it. If we assume two clients are concurrently writing to the server. The server will wake up to one of them but what will happen to the other one? is the server still "listening" while handling the request from the first client? I know that the bind function takes an int as the second argument that specifies the backlog (5 by default). does that mean that only 5 clients can connect concurrently to a server? If thats true, how are servers that handle multiple concurrent connections are implemented?

Barytes answered 16/7, 2015 at 18:6 Comment(0)
B
2

You should threads. Usually servers have a main thread which listens for connections. If a connection is made, the main thread creates another thread and passes that connection to the newly created thread. This way the connections are handled while the main thread is still able to listen for new connections.

Edit: Here is the listen():

listen(int socket_fd, int backlog)

For a given listening socket, the kernel maintains two queues:

  • An incomplete connection queue for which SYN has been received but three-way handshaking (TCP) has not completed. (SYN_RCV state) A complete connection queue.
  • Three-way handshaking done. (ESTABLISHED state) the backlog argument historically specifies sum of both queues. But there is no formal definition of what backlog means.
Bandoleer answered 16/7, 2015 at 18:18 Comment(4)
This is exactly how I am implementing it. My question is what if multiple connections happen before the main thread dispatches the connection to a thread.Barytes
@Barytes so when a connection is established. A new thread is created and then the connection is passed to it. If during this process a new connection comes it will be queued until the process is free.Bandoleer
Yes, you can use a thread per connection. Then the time comes when you have more simultaneous clients then cores in the box.Heyes
@NikolaiNFetissov TrueBandoleer
H
5

The select(2) and poll(2) system calls were invented to deal with this exact situation (with non-blocking sockets).

Then there is a multi-process approach with fork(2), and then, of course, the server could be implemented with threads.

The best solution for your case depends on your specific requirements.

Heyes answered 16/7, 2015 at 18:20 Comment(0)
W
3

using this function in the server:

int listen(int sockfd, int backlog); 

The 'backlog' indicates how many outstanding clients can be trying to connect at one time.

When this function returns:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);  

then immediately , passing the 'sockfd' parameter to the

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                      void *(*start_routine) (void *), void *arg);  

to have the thread handle the communication with the client.

Note: creating a thread is expensive and slow, so a 'pool' of threads should be initially created and activate one for each client connection and when the client disconnects, return the thread to the pool

Woodchopper answered 16/7, 2015 at 19:0 Comment(0)
B
2

You should threads. Usually servers have a main thread which listens for connections. If a connection is made, the main thread creates another thread and passes that connection to the newly created thread. This way the connections are handled while the main thread is still able to listen for new connections.

Edit: Here is the listen():

listen(int socket_fd, int backlog)

For a given listening socket, the kernel maintains two queues:

  • An incomplete connection queue for which SYN has been received but three-way handshaking (TCP) has not completed. (SYN_RCV state) A complete connection queue.
  • Three-way handshaking done. (ESTABLISHED state) the backlog argument historically specifies sum of both queues. But there is no formal definition of what backlog means.
Bandoleer answered 16/7, 2015 at 18:18 Comment(4)
This is exactly how I am implementing it. My question is what if multiple connections happen before the main thread dispatches the connection to a thread.Barytes
@Barytes so when a connection is established. A new thread is created and then the connection is passed to it. If during this process a new connection comes it will be queued until the process is free.Bandoleer
Yes, you can use a thread per connection. Then the time comes when you have more simultaneous clients then cores in the box.Heyes
@NikolaiNFetissov TrueBandoleer

© 2022 - 2024 — McMap. All rights reserved.