简体   繁体   中英

Linux threaded C server

I wrote this server based on an online tutorial. My aim is to create a new thread for every new client connection. This part works fine but the problem is that the server program quits whenever one of the clients disconnects. What am I doing wrong ?

#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <netinet/in.h>
#include <resolv.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

void* SocketHandler(void*);

int main(int argv, char** argc){
    int host_port= 1101;
    struct sockaddr_in my_addr;
    int hsock;
    int * p_int ;
    int err;
    socklen_t addr_size = 0;
    int* cs;
    struct sockaddr_in sadr;
    pthread_t thread_id=0;

    hsock = socket(AF_INET, SOCK_STREAM, 0);
    p_int = (int*)malloc(sizeof(int));
    *p_int = 1;

    setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int));
    setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int));
    free(p_int);

    my_addr.sin_family = AF_INET ;
    my_addr.sin_port = htons(host_port);
    memset(&(my_addr.sin_zero), 0, 8);
    my_addr.sin_addr.s_addr = INADDR_ANY ;

    bind( hsock, (struct sockaddr *)&my_addr, sizeof(my_addr));
    listen( hsock, 10);
    addr_size = sizeof( struct sockaddr_in);

while(1){
    printf("waiting for a connection\n");
        cs = (int*)malloc(sizeof(int));
    if((*cs = accept( hsock, (struct sockaddr*)&sadr, &addr_size))!= -1){
        pthread_create(&thread_id,0,&SocketHandler, (void*)cs );
        pthread_detach(thread_id);
    }
    else{
        fprintf(stderr, "Error accepting %d\n", errno);
    }
    }
}

void* SocketHandler(void* lp){
    int *csock = (int*)lp;
    char buffer[1024];
    int buffer_len = 1024;
    int bytecount;
    while (1){
    memset(buffer, 0, buffer_len);
        bytecount = recv(*csock, buffer, buffer_len, 0);
    printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);

    strcat(buffer, " SERVER ECHO");
    bytecount = send(*csock, buffer, strlen(buffer), 0);    
    printf("Sent bytes %d\n", bytecount);
    }
    free(csock);
    return NULL;
}

If you attempt to send() to a socket that has been closed the signal SIGPIPE is raised. If you don't ignore or handle this signal it will terminate the process.

To ignore:

sigset(SIGPIPE, SIG_IGN); /* check return value to ensure success. */

To handle you need to define and specify a signal handler function.

Your SocketHandler routine don't handle end-of-file conditions. recv (or read ) gives 0 in that case.

And you probably should use the shutdown syscall to shut down a connection.

My first thought is that you never actually close the connection to a socket. Inside your thread you have an infinite loop and nothing inside to break it.

Try something like

while ((bytecount = recv(*csock, buffer, buffer_len, 0)) > 0) {
   printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
   strcat(buffer, " SERVER ECHO");
   bytecount = send(*csock, buffer, strlen(buffer), 0);
   printf("Sent bytes %d\n", bytecount);
   memset(buffer, 0, buffer_len);
}
// bytecount should be <0 for an error or == 0 for EOF received from sender

shutdown(csock, SHUT_WR);
close(*csock)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM