Search code examples
csocketsubuntuserverfork

Trying to fork() after new client connection to server [Socket Programming C]


So I have a server that is supposed to create a new process for every new connection to the server. Therefore I will have multiple clients connecting to one server.

When a connection is made the server should return a random number id for each new client.

PROBLEM: the server is printing the same random number id for all the clients (terminals) connecting to the server.

What should happen: child process should generate (rand()) id for a new unique client connection. Proving each new client is being connected to the server. Is my fork correct?

while (1)
{
    pid_t childpid; /* variable to store child's process id */

    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);

    if ((childpid = fork()) == -1)
    { // fork failed.
        close(new_fd);
        continue;
    }
    else if (childpid > 0)
    { // parent process
        printf("\n parent process\n");
    }
    else if (childpid == 0)
    { // child process
        printf("\n child process\n");

        printf("\n random num: %d\n", rand());    -----> Testing, should be unique for each client (its not!)

        /* ***Server-Client Connected*** */
        client_t client = generate_client();

    }
    printf("server: got connection from %s\n",
           inet_ntoa(their_addr.sin_addr));
}

Solution

  • The 'rand' function uses a hidden 'state' to generate the next random number. Since the parent never uses rand, each forked child will get the same state, and will generate the same sequence of random number.

    Few possible fixes:

    • Make one call to rand in the parent (BEFORE forking). This will result in each child starting with different state.
    • Call rand in the parent, before the fork, and save the id for the child to use.
    • Setup random see for each child, using srand.
        int child_id = rand() ;
        if ((childpid = fork()) == -1)
        { // fork failed.
            close(new_fd);
            continue;
        }
        ... Later in the child.
            printf("random num: %d", child_id) ;