質問

on multiple client request the given server code should respond with a sequential number for each client request. Also for each client request the server should fork a process. the child process then waits for 5 seconds and decrements the client request count. So basically its a token system.

the problem in the code is that when i send multiple client request except the first request others get blocked for 5 seconds which i don't want.

static int num = 0;

int main(int ac, char *av[]){

    struct sockaddr_in saddr;
    struct hostent *hp;
    char hostname[HOSTLEN];
    int sock_id, sock_fd;
    FILE *sock_fp;
    int pid, fd[2];
    pipe(fd);

    sock_id = socket(PF_INET, SOCK_STREAM, 0);
    if(sock_id == -1)
            oops("Socket");

    bzero((void *)&saddr, sizeof(saddr));

    gethostname(hostname, HOSTLEN);
    hp = gethostbyname(hostname);

    bcopy((void *)hp->h_addr, (void *)&saddr.sin_addr, hp->h_length);
    saddr.sin_port = htons(PORTNUM);
    saddr.sin_family = AF_INET;

    if(bind(sock_id, (struct sockaddr *)&saddr, sizeof(saddr)) != 0)
            oops("bind");

    if(listen(sock_id, 5) != 0)
            oops("listen");
    while(1) {
            sock_fd = accept(sock_id, NULL, NULL);
            printf("got a call\n");
            if(sock_fd == -1)
                    oops("accept");

            num++;

            sock_fp = fdopen(sock_fd, "w");
            if(sock_fp == NULL)
                    oops("fdopen");
            fprintf(sock_fp, "Your token number is: %d\n", num);
            fclose(sock_fp);

            pid = fork();

            if(pid == 0){
                    close(sock_id);
                    sleep(5);
                    num--;

                    close(fd[0]);
                    write(fd[1], &num, sizeof(num));
                    printf("Sent: %d\n", num);
                    close(fd[1]);
                    exit(0);
            }
            else if(pid > 0){
                    close(fd[1]);
                    read(fd[0], &num, sizeof(num));
                    printf("Received %d\n", num);
                    close(fd[0]);
                    close(sock_fd);
            }

    }
役に立ちましたか?

解決

In the parent process, you try to read from an empty pipe, the read() will block until data is available, so it blocks until child process wakes up and call write(). Write something to the pipe after you call pipe(),

pipe(fd);
write(fd[1], &num, sizeof(num));

it would solve your problem.

And what Joachim Pileborg says about handling reaping of the child processes is important.

他のヒント

The problem is probably that after the fork, in the parent you close both ends of the pipe, so next iteration of the infinite loop you try to use the pipe but it's already closed.


You should also handle reaping of the child processes, otherwise they become zombies until the parent process exits. This can be done by installing a signal handler for SIGCHLD and in the signal handler call wait.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top