recv: Connection reset by peer
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;
}
Sarp Kaya
Updated on July 09, 2022Comments
-
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; }