Ravi Nankani
Ravi Nankani

Reputation: 599

socket close inside fork c++

I am trying socket programming and with the server code:

    while(1) {
    sin_size = sizeof (their_addr);
    new_fd = accept(sockfd,(struct sockaddr *)&their_addr, &sin_size);
    if(new_fd == -1) {
        perror("accept");
        continue;
    }

    inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr*)&their_addr),s,sizeof(s));
    cout<<"got connection from" << s << endl;

    if((pid = fork()) == 0){//child
        close(sockfd);
        if(send(new_fd,"hello world!",12,0) == -1) {
            perror("send");
            close(new_fd);
            exit(0);
        }
        char buf[50];
        int numbytes;
        if((numbytes = recv(new_fd,&buf,50,0)) == -1) {
            perror("receive");
            close(new_fd);
            exit(0);
        }
        buf[numbytes] = '\0';
        cout<<"numbytes" << numbytes <<endl;
        cout<<"server received " << buf <<endl;
    }
    close(new_fd);
}

this code gives me a bad file descriptor, however when i comment the close(sockfd), the code runs fine. Since I am forking to a new child process and closing the listening port , why am I getting a bad file descriptor? Is there something I am missing here.

Upvotes: 0

Views: 760

Answers (2)

I know it is almost 2 years since the question was posed, but I had the same issue, and after googling around and not finding anything I decided to try working on it for a while. I found the issue to be that you don't close the child process unless there's a send error. So instead of having this:

if (send(new_fd,"hello world!",12,0) == -1) {
    perror("send");
    close(new_fd);
    exit(0);
}

Move the closing bracket right below the perror like this:

if (send(new_fd,"hello world!",12,0) == -1) {
    perror("send");
}    
close(new_fd);
exit(0);

By doing this, you force the child process to close right after sending the message. I'm not entirely sure, but I think that the Bad file descriptor comes from the call to accept, by the forked child process, which hasn't been closed but has a Bad file descriptor, since you've closed the listening socket for this process.

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409136

You close new_fd twice. After you receive you close it once, then the child process continues and close it again. You should put that second close only in the parent process, or not close at all inside the if (fork()) body.

Upvotes: 1

Related Questions