recv: Connection reset by peer

23,353

This if-statement is what you need to look at:

if ((numbytes=recv(new_fd, buf, MAXDATASIZE, 0)) == -1) {
    perror("recv");
    exit(1);
}

It's the only place you posted that has recv, so that's the error.

Take a look at the man page: recv returns the length of the message on successful completion. If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on the type of socket the message is received from. If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking (see fcntl(2)), in which case the value -1 is returned and the external variable errno is set

So instead of having a call to exit (which terminates the process), try handling the error gracefully:

if ((numbytes=recv(new_fd, buf, MAXDATASIZE, 0)) < 0) {
    // user disconnected or timeout (if you set a timeout)
    // NO call to exit; use "continue" or "return", or something else
    // to gracefully handle the break;
    my_error_function("client disconnected\n");
    break;
}
Share:
23,353
Sarp Kaya
Author by

Sarp Kaya

Updated on July 09, 2022

Comments

  • Sarp Kaya
    Sarp Kaya almost 2 years

    when I close my client connected to the server I get this error from the server and server shuts itself down. I know that client can terminate the connection gracefully but I am planning to send this out to some people and do not want my server to be shut just because they did not terminate gracefully. So what could actually prevent the server to be closed? I am using sys/socket.h

    Here's a part of my code

    int server() {
        //Set up variables
        int sockfd, new_fd;  //Listen on sock_fd, new connection on new_fd
        struct sockaddr_in my_addr;    //My(server) address information
        struct sockaddr_in their_addr; //Connector's address information
        socklen_t sin_size;
        //Generate the socket
        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
            perror("socket");
            exit(1);
        }
        //Generate the end point
        my_addr.sin_family = AF_INET;         //Host byte order 
        my_addr.sin_port = htons(MYPORT);     //Short, network byte order 
        my_addr.sin_addr.s_addr = INADDR_ANY; //Auto-fill with my IP 
    
        if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) \
        == -1) {
            perror("bind");
            exit(1);
        }
    
        //Start listnening
        if (listen(sockfd, BACKLOG) == -1) {
            perror("listen");
            exit(1);
        }
    
        while(TERMINATE == 0) {  // main accept() loop 
            sin_size = sizeof(struct sockaddr_in);
            //Create a new connection for the accepted socket
            if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, \
            &sin_size)) == -1) {
                perror("accept");
                continue;
            }
    //some semaphore stuff      
        }
        return 0;
    }   
    
    
    
    int main(int argc, char *argv[]){
    
    //extra stuff
    
            //Set up mutex locks
            pthread_mutex_init(&mutex, NULL);
            sem_init(&empty, 0, 30);
            sem_init(&full, 0, 0);
    
            //Set up and run Threads
            pthread_t threads[30]; //Array of threads
            pthread_t server_thread;
            pthread_attr_t attr; //Set of thread attributes
    
            //Get the default thread attributes
            pthread_attr_init(&attr); 
            signal(SIGINT, termination);//Wait for a SIGINT
            //Loop to create threads and execute consumer_thread
            for (int i = 0; i < 30; i++) {
                //Set up data in structure
                threadArray[i].threadID = i;
                threadArray[i].running = 0;
                threadArray[i].line_counter_pointer = &line_counter;
                threadArray[i].vid_details_pointer = &vid_details;
                pthread_create(&threads[i],&attr,consumer_thread, &threadArray[i]); 
            }
            //Execute the producer_thread   
            pthread_create(&server_thread,&attr,producer_thread, NULL);
    
            //Wait for all the threads to exit
            for (int i = 0; i < 30; i++) {
                pthread_join(threads[i],NULL);
            }
            //Destroy semaphores so that it can TERMINATE gracefully
            sem_destroy(&empty);
            sem_destroy(&full);
            return 0;
        }
    void *producer_thread(void *param) {
        server();//Runs the server() function
        return NULL;
    }
    
        void *consumer_thread(void *param) {
            //Pass variable
            struct thread_params *threadStruct;
            threadStruct = (struct thread_params *) param;
            int *line_counter = threadStruct->line_counter_pointer;
            vid_details_struct *vid_details = threadStruct->vid_details_pointer;
            //End of pass   
            char found_result [MAXDATASIZE];
            int queue_item = 0;
            int numbytes;
            struct timeval item_wait_time;// Get the current time
    
            while (TERMINATE == 0) { //Main accept() loop
                int new_fd;
                //Use a variable that would be set to 0 after the client termination 
                //so that the current connection will be closed on both thread and 
                //client, that would make thread to go back to idle
                int current_connection = 1;
                //Acquire full semaphore
                sem_wait(&full);
                //Acquire mutex lock to protect buffer
                pthread_mutex_lock(&mutex);
        //some extra stuff including socket information
                //now handling queue[queue_item]
                new_fd = queue[queue_item].new_fd;
                queue[queue_item].waiting = 0;
    
                //Release mutex lock and empty semaphore
                pthread_mutex_unlock(&mutex);
                sem_post(&empty);   
                while (current_connection == 1) {
                    char buf[MAXDATASIZE];
                    //Receive the query
                    if ((numbytes=recv(new_fd, buf, MAXDATASIZE, 0)) == -1) {
                        perror("recv");
                        exit(1);
                    }           
    
                    buf[numbytes] = '\0';//Set the end point of the string
                    if (!strcmp(buf,"q")) {//Client prompts to TERMINATE
                        current_connection = 0;//Flag the connection as closed
                    }
                    if (current_connection == 1) {//If still connected
        //do something
                        if (send(new_fd, found_result, MAXDATASIZE, 0) == -1) {
                            perror("send");
                            close(new_fd);
                            exit(0);
                        }
                    }
                }
                close(new_fd); // Close the socket connection
                //Wait for half a second before accepting a new request
                usleep(500000);
            }//End of the main while loop
            FINISHEDSEMS++;
            printf("Thread %d is closing\n", threadStruct->threadID);
            return NULL;
        }