2

ここに私のフォークサーバーコードの一部があります:

    signal (SIGINT, ( void *)sig_handler);
while(1){
    memset(&cli_addr, 0, sizeof(cli_addr));

    if((newsockd = accept(sockd, (struct sockaddr *) &cli_addr, (socklen_t *) &socket_len)) < 0){
        perror("Errore nella connessione\n");
        onexit(newsockd, sockd, 0, 2);
    }
    fprintf(stdout, "Ricevuta richiesta di connessione dall' indirizzo %s\n", inet_ntoa(cli_addr.sin_addr));

    child_pid = fork();
    if(child_pid < 0){
        perror("Fork error");
        onexit(newsockd, sockd, 0, 2);
    }
    if(child_pid == 0){
        do_child(newsockd);
    }
    else{
        attended_pid = waitpid(child_pid, NULL, 0);
        if(attended_pid != child_pid){
            printf("Child error");
        }
    }
}

私の質問は、クライアントを実行する前にメインソックス(sockd)を閉じる必要がありますか?
私はノーだと思います:

  • 「sigintコントローラー」を追加しました。サーバーでCTRL-Cを押すと(コメント付きのsockd-> //close(sockd);)、sigintは2つの同時接続で3回実行されます(なぜ??)
  • このコードを持っている場合close(sockd)、sigintは1回だけ実行されますが:bad file descriptoraccept命令を取得しました。

だから、私は何をする必要がありますか?
ありがとう!

PS:私のシギントコード:

void sig_handler(const int signo, const int sockd, const int newsockd){
  if (signo == SIGINT){
    printf("Ricevuto SIGINT, esco...\n");
    if(newsockd) close(newsockd);
    if(sockd) close(sockd);
    exit(EXIT_SUCCESS);
  }
}
4

1 に答える 1

2

fork(2)マニュアルページから:

子は、親の開いているファイル記述子のセットのコピーを継承します。子の各ファイル記述子は、親の対応するファイル記述子と同じ開いているファイルの説明(open(2)を参照)を参照します。これは、2つの記述子がオープンファイルステータスフラグ、現在のファイルオフセット、および信号駆動型I / O属性を共有することを意味します(fcntl(2)のF_SETOWNおよびF_SETSIGの説明を参照)。

これは、子プロセスでリスニングソケットを閉じてはならないことを示しています。親プロセスでも受け入れられたソケットを閉じるべきではありませんが、完了したら子プロセスによって閉じられるようにします。

于 2012-09-05T07:43:10.240 に答える