Server can accept n clients only

168 views Asked by At

I'm programming a server code using C language that must accept only few numbers of clients and if extra one arrives the server will put that client to wait until one of the old clients terminated.

For example (The server can accept 10 clients only, if new client arrived the server will put that client to wait until one of the 10 clients terminated, then he can be served).

I know i have to use signal() function, after listen() function and before accept() and create a value that counts the number of clients, but i don't know how to use it correctly.

Can any one give me a hint or simple example.

Thank you,,,,,,

1

There are 1 answers

0
Armali On BEST ANSWER

There is no need to use signal(). Example:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

main()
{
    int s = socket(PF_INET, SOCK_STREAM, 0);    // server socket
    if (s            == -1) return perror("socket"), 1;
    if (listen(s, 0) == -1) return perror("listen"), 1;
    const int n = 10;   // number of clients allowed to be served
    fd_set fds, rfds;
    FD_ZERO(&fds);
    FD_SET(s, &fds);    // initially, set of sockets holds server
    int nfds = s+1, fd, clients = 0;
    while (rfds = fds, select(nfds, &rfds, NULL, NULL, NULL) > 0)
        for (fd = 0; fd < nfds; ++fd)
            if (FD_ISSET(fd, &rfds))    // see which sockets of set are ready
                if (fd == s)            // is it the server socket?
                {   // yes, so it is a client's connection request
                    printf("new client request ");
                    struct sockaddr_in sa = { AF_INET, 0, INADDR_ANY };
                    socklen_t sal = sizeof sa;
                    int c = accept(s, (struct sockaddr *)&sa, &sal);
                    if (c == -1) return perror("accept"), 1;
                    FD_SET(c, &fds); if (nfds <= c) nfds = c+1; // add client
                    printf("accepted (fd=%d) # clients now %d\n", c, ++clients);
                    if (clients == n)   // allowed number hit?
                        puts("Further client requests will be ignored."),
                        FD_CLR(s, &fds);    // don't watch server now
                }
                else
                {   // this is a client's message or termination
                    printf("client fd=%d: ", fd);
                    char buf[BUFSIZ];
                    size_t count = read(fd, buf, sizeof buf);
                    if (count > 0) fwrite(buf, 1, count, stdout);
                    else
                    {   // no more data from client, so close the connection
                        close(fd);
                        FD_CLR(fd, &fds);   // remove client from watch set
                        printf("closed, # clients now %d\n", --clients);
                        if (clients == n-1) // went just below allowed number?
                            FD_SET(s, &fds),    // watch server again
                            puts("New client requests will be accepted again.");
                    }
                }
    return perror("select"), 1;
}

Note: This program binds to a random free port, which you can find out with e. g. netstat -tlp. Of course you can also bind() to a specific address and port. In any case you can test it with e. g. nc hostname port.