2016-05-15 7 views
0

私は、クライアントの1つを終了すると、pselect関数のエラーが悪いfiledescriptor(私はその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; 
} 
+0

pselectに失敗したときに 'maxfd'の値を出力できますか? –

+0

@MarkPlotnickはい私はできるが、このfdはクライアントが閉じてからもう有効ではない。 – HackTheGibson

+0

私が見たいのは、 'maxfd'が' fd_set'のサイズより大きくなるかどうかです。 'add_new_client'は常に正の数を返しますか?それでmaxfdは決して減少しません。 –

答えて

1

あなたは閉じているソケット上で選択されています。ソケットを閉じるときには、FDセットからソケットを削除する必要があります。このセットの扱いはかなり楽観的です。たとえば、新しいクライアントを追加すると実際に最大FDを増やすことはできません。私はまた、あなたが一度セットからリスニングソケットを取り除いている理由を理解していません。 select()のサンプルコードを見る必要があります。これはすべて非常に奇妙です。

関連する問題