recv:通过对等方重置连接

时间:2012-12-06 02:35:21

标签: c sockets recv

当我关闭连接到服务器的客户端时,我从服务器收到此错误,服务器自行关闭。我知道客户端可以优雅地终止连接,但我打算将其发送给某些人,并且不希望我的服务器被关闭只是因为它们没有正常终止。那么什么可以阻止服务器关闭呢? 我正在使用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;
    }

2 个答案:

答案 0 :(得分:2)

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

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

这是您发布的唯一有recv的地方,所以这就是错误。

查看man pagerecv返回成功完成时消息的长度。如果消息太长而无法容纳在提供的缓冲区中,则可能会丢弃多余的字节,具体取决于接收消息的套接字类型。如果套接字上没有消息可用,则接收调用等待消息到达,除非套接字是非阻塞的(参见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 :(得分:0)

'由peer重置连接'有许多原因,但最常见的是您已写入已由对等方关闭的连接。换句话说,应用程序协议错误。