2

这是我的 fork-server 代码:

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

我的问题是:我必须在执行客户端之前关闭主 sock (sockd) 吗?
我认为没有,但是:

  • 我添加了一个“sigint 控制器”,如果我在服务器上按 CTRL-C(带有注释 sockd -> //close(sockd);),sigint 将在 2 个并发连接的情况下执行 3 次(为什么??)
  • 如果我有此代码close(sockd),则 sigint 将仅执行 1 次,但我得到了一条:bad file descriptor指令accept

那么,我该怎么办?
谢谢!

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))。这意味着两个描述符共享打开文件状态标志、当前文件偏移量和信号驱动的 I/O 属性(参见 fcntl(2) 中对 F_SETOWN 和 F_SETSIG 的描述)。

这告诉我你不应该关闭子进程中的监听套接字。您也不应该在父进程中关闭已接受的套接字,而应在子进程完成后将其关闭。

于 2012-09-05T07:43:10.240 回答