Home > front end >  Why my simple C server exits when the client closes connection?
Why my simple C server exits when the client closes connection?

Time:12-20

#include <stdio.h>
#include <stdlib.h>     /* exit() */
#include <strings.h>    /* bzero(), bcopy() */
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>

int main(int argc, char **argv){

    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    
    struct sockaddr_in my_addr;
    bzero(&my_addr,sizeof my_addr);
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(9999);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    int res;
    res = bind(sockfd,(struct sockaddr *)&my_addr,sizeof (struct sockaddr_in));
    
    res = listen(sockfd,5);
    
    while (1) {     // shouldn't this while cycle "keep alive" the server to wait for new clients?
        struct sockaddr_in cli_addr;
        bzero(&cli_addr,sizeof cli_addr);
        socklen_t cli_size = sizeof (struct sockaddr_in);
        int clisockfd = accept(sockfd,(struct sockaddr *)&cli_addr,&cli_size);

        while (1) {
            char buf[100] = "";
            int b_recv = recv(clisockfd, buf, 100, 0);
            printf("%d %d\n",sockfd,b_recv);
            printf("%s\n",buf);
            char string[] = "test";
            send(clisockfd,string,sizeof string,0))
        }
    }
}

If I test my server with netcat, if I close netcat the server exits. Why? Shouldn't the external while loop keep it alive? Why and how can I avoid that the server closes?

CodePudding user response:

If you check closely the server will be terminated with a SIGPIPE signal when you close the connection from the client-side.

It happens because you don't check for closed-connection events, and attempt to write to the closed connection.

When recv return 0 you should not attempt to write to the connected socket. Instead you should close the socket and break out of the inner recv/send loop.

while (1) {
    char buf[100] = "";
    int b_recv = recv(clisockfd, buf, 100, 0);
    printf("%d %d\n",clisockfd,b_recv);  // Print the connection socket instead
    if (b_recv <= 0) {
        // Error or closed connection
        close(clisockfd);
        break;  // Go back to the outer loop, wait for new connections
    }
    printf("%s\n",buf);
    char string[] = "test";
    send(clisockfd,string,sizeof string,0))
}
  • Related