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

2 に答える 2

2

この if ステートメントを確認する必要があります。

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

あなたが投稿した唯一の がある場所なrecvので、それがエラーです。

man ページを見てみましょう:正常に完了すると、メッセージの長さが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;
}
于 2012-12-06T03:52:25.420 に答える
0

「ピアによる接続のリセット」にはいくつかの原因がありますが、最も一般的な原因は、ピアによってすでに閉じられている接続に書き込んだことです。つまり、アプリケーションプロトコルエラーです。

于 2012-12-06T10:09:40.877 に答える