c - 错误的文件描述符错误处理

标签 c sockets unix posix errno

我正在练习 POSIX 编程套接字,我的服务器有以下问题,当我终止其中一个客户端时,函数 pselect 收到错误错误文件描述符(我认为它的 errno=EBADF),你能帮我写一下如何我在代码中避免使用它吗?

这是我写的:

void doServer(int fd) {
//fd is the listening socket (there is only one)
int maxfd = fd;
//base, and reading fd set
fd_set base_rfds, rfds;
int i;
sigset_t mask, oldmask;
//zero out base fd set
FD_ZERO(&base_rfds);
//add listening socket to base fd set
FD_SET(fd, &base_rfds);
//add SIGINT to blocking signal mask
sigemptyset (&mask);
sigaddset (&mask, SIGINT);
sigprocmask (SIG_BLOCK, &mask, &oldmask);
//main server loop (block on pselect untill fd changes or we get signal)
while(!stop){
    rfds=base_rfds;
    //call pselect with oldmask to not block SIG_INT
    if(pselect(maxfd+1,&rfds,NULL,NULL,NULL,&oldmask)>0){

        if(FD_ISSET(fd,&rfds)){
            //connect client
            maxfd+=add_new_client(fd, &base_rfds);
            //remove listening socket from reading fd set
            FD_CLR(fd,&rfds);
        }
        //remove listening socket from base fd set
        FD_CLR(fd,&base_rfds);
        handle_connection(rfds,&base_rfds,maxfd);
        //add listening socket back into base fd set
        FD_SET(fd,&base_rfds);
    }
    else{
        if(EINTR==errno) continue;
        ERR("select");
    }
}
//close all of fd's from connected clients
for(i=0;i<maxfd;i++) 
    if(FD_ISSET(i,&base_rfds) && TEMP_FAILURE_RETRY(close(i))<0)ERR("close");
sigprocmask (SIG_UNBLOCK, &mask, NULL);
}

编辑: 这是 add_new_client 函数:

int add_new_client(int sfd, fd_set *base_rfds){
int nfd,new_flags;
//accept now if we can (non-blocking)
if((nfd=TEMP_FAILURE_RETRY(accept(sfd,NULL,NULL)))<0) {
    if(EAGAIN==errno||EWOULDBLOCK==errno) return 0;
    ERR("accept");
}
//remember to make the fd non-blocking
//get current flags, add O_NONBLOCK
new_flags = fcntl(nfd, F_GETFL) | O_NONBLOCK;
//apply new flags
fcntl(nfd, F_SETFL, new_flags);
//add discriptor to base fd set
FD_SET(nfd,base_rfds);
return 1;
}

最佳答案

您正在选择已关闭的套接字。当您关闭套接字时,您需要将其从 FD 集中删除。你对这组的处理似乎相当乐观。例如,您无法确定添加新客户端是否真的会增加最大 FD。我也不明白为什么你要从集合中删除监听套接字一次,更不用说两次,然后恢复它。您需要查看 select() 的一些示例代码。这一切都很奇怪。

关于c - 错误的文件描述符错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37243197/

相关文章:

C - 访问 malloc 内存后的 SIGSEGV

c - 重复调用 C 函数会导致 R - 如何分配内存?

java - Android套接字连接组合发送

python - 套接字错误 : [Errno 10054] An existing connection was forcibly closed by the remote host (python2. 7)

C 中的计数制表符、空白和换行符

c - 该程序中的内存将如何组织?

javascript - 我可以通过 Javascript 建立套接字连接吗

linux - 保护包含空格的参数免受 eval 的影响

shell - 使用 UNIX 命令替换 csv 中的字符或修复不正确的换行符

linux - 未找到 Sudo 命令(Jenkins 执行 shell 时出错)