Grace O'Brien
Grace O'Brien

Reputation: 121

Limiting Clients From Connecting

Trying to limit the amount of client connections in my client-server c application. This is what I have, however it doesn't work. (Doesn't even recognise when max_connections is reached. How can I fix this?

int main(int argc, char *argv[])
{
        //fill db
        if (obtainDb() == false) {
                printf("Database obtain error.\n");
                exit(true);
        }
        //initialise variables
        total_connections = 0;

        /* generate the socket */
        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                perror("socket");
                exit(true);
        }

        /* generate the end point */
        my_addr.sin_family = AF_INET;         // host byte order
        my_addr.sin_port = htons(MYPORT);     // short, network byte order
        my_addr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP

        /* bind the socket to the end point */
        if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) \
        == -1) {
                perror("bind");
                exit(true);
        }

        /* start listnening */
        if (listen(sockfd, BACKLOG) == -1) {
                perror("listen");
                exit(true);
        }

        printf("server starts listnening ...\n");

        while(true){
                sin_size = sizeof(struct sockaddr_in);

                if (total_connections == max_connections) {
                        printf("Max Number of clients connected!\n");
                        while(total_connections == max_connections);
                }

                if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, \
                &sin_size)) == -1) {
                        perror("accept");
                        continue;
                }
                total_connections++;
                printf("server: got connection from %s\n", \
                        inet_ntoa(their_addr.sin_addr));

                userInput();

                while(waitpid(-1,NULL,WNOHANG)>0);

        }

        return false;

}

Thanks

Edit: UserInput():

void userInput(void) {
if (!fork()) { // this is the child process
    while(true){
        char buffer[MAXDATASIZE];
        char res[MAXDATASIZE];

        memset(buffer, '\0', MAXDATASIZE);
            memset(res, '\0', sizeof(res));

        if ((numbytes=recv(new_fd, buffer, sizeof(buffer), 0)) == -1) {
            perror("recv");
            exit(true);
        }
        if (numbytes == 0) {
            printf("client left");
            close(new_fd);
            total_connections--;
            exit(false);
        }
        buffer[numbytes] = '\0'; // add null terminator
        printf("Request: %s\n",buffer);
        search(buffer,res);
    }
    close(new_fd);  // parent doesn't need this
    exit(false);
}
close(new_fd);

}

Upvotes: 1

Views: 151

Answers (2)

Dariusz
Dariusz

Reputation: 22251

Forking creates a new instance of your proces, which also means that each variable is copied to the new process. Your initial total_connections will actually never get increased beyond 1.

C fork dealing with global variable

A relatively simple option would be to use threads instead of processes for handling multiple clients simultaneously.

Upvotes: 1

Klas Lindbäck
Klas Lindbäck

Reputation: 33273

When you fork all variables are copied to the new process. That means that the children have their own copy of total_connections.

Instead of using a variable, you should use wait to find out whether any children have exited.

Upvotes: 2

Related Questions