0
我正在練習POSIX編程套接字,我有我的服務器,當我終止其客戶端之一,函數pselect獲取錯誤錯誤filedescriptor(我認爲它errno = EBADF),你能幫我我並寫我如何可以在我的代碼中避免它?糟糕的filedescriptor錯誤處理
這裏是我寫的:
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;
}
當你得到pselect失敗時,你能打印出'maxfd'的值嗎? –
@MarkPlotnick是的,我可以,但這個FD不再有效,因爲客戶端關閉。 – HackTheGibson
我希望看到的是'maxfd'是否大於'fd_set'的大小。 'add_new_client'總是返回一個正數嗎?那麼maxfd永遠不會減少。 –