recv:连接被对等方重置

问题描述 投票:0回答:2

当我关闭连接到服务器的客户端时,我从服务器收到此错误,并且服务器自行关闭。我知道客户端可以优雅地终止连接,但我计划将其发送给某些人,并且不希望我的服务器仅仅因为他们没有优雅地终止而被关闭。那么什么才能真正阻止服务器关闭呢? 我正在使用 sys/socket.h

这是我的代码的一部分

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;
    }
c sockets recv
2个回答
3
投票

这个 if 语句是您需要查看的内容:

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

这是您发布的唯一有

recv
的地方,所以这就是错误。

查看手册页:成功完成后,

recv
返回消息的长度。如果消息太长而无法放入所提供的缓冲区,则可能会丢弃多余的字节,具体取决于接收消息的套接字类型。如果套接字上没有可用消息,则接收调用将等待消息到达,除非套接字是非阻塞的(请参阅 fcntl(2)),在这种情况下,返回值 -1 并设置外部变量 errno

因此,不要调用

exit

 (这会终止进程),而是尝试优雅地处理错误:

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; }
    

1
投票

Connection reset by peer

 有多种原因,但最常见的一个是您写入的连接已被对等方关闭;否则,连接已被对等方关闭而未读取所有挂起的数据,这是类似但不完全相同的事情。无论哪种情况,都会出现应用程序协议错误。

© www.soinside.com 2019 - 2024. All rights reserved.