2012-05-02 72 views
1

我得到一個奇怪的結果,而與選擇試驗()。選擇一直等待下去

fd_set tempset,set; //set of descriptors 

FD_ZERO(&set); //initialize descriptor set to NULL 

FD_SET(serversock,&set); //add server's socket to descriptor set 'set' 

timeout.tv_sec=2; 
timeout.tv_usec=0; 

while(1){ 

tempset=set; 
timeout.tv_sec=2; 
timeout.tv_usec=0; 

printf("%s","Waiting on select\n"); 

int ret=select(FD_SETSIZE,&tempset,NULL,NULL,&timeout); 

if(ret==0) printf("timeout "); 

else if(ret==-1){ 
    printf("Error occured\n"); 
    exit(0); 
} 

else if(ret>0){ //socket ready for reading 

    for(i=0;i<FD_SETSIZE;i++){ 

    if(FD_ISSET(i,&tempset)){ //check if it's serversock 

     if(i==serversock){ 
       //accept connection and read/write 
       printf("Client connected\n"); 

    }//i==serversock close 

    } 
}//for ends 
} 

當我刪除行printf(「%s」,「等待選擇\ n」);選擇不停地等待。然而,當我重新插入線,一切正常(與客戶端連接測試)

我這麼想嗎?

在此先感謝!

+0

您需要重新初始化文件描述符之前給每個呼叫設置在這個循環中進行選擇。 –

+0

您可能有stdio緩衝效果。嘗試在你的「超時」消息中增加一個換行符,例如'printf(「timeout \ n」);'看看你是否改變了你所觀察到的。我敢打賭,你的'選擇()'實際上是超時每2秒,但你不能看到它沒有頂部'printf'沖洗'stdout'行緩衝區。 – Celada

+0

是的,超時後添加一個新行可以解決這個問題。謝謝! 但爲什麼標準輸出需要以被刷新爲選擇工作? – Karan

回答

3

你misususing FD_SETSIZE,你不應該使用直接的。你只是把一個插座到fd_set,所以沒有必要甚至可以通過它循環在所有(但如果你確實需要,使用fd_set.fd_count成員,而不是)。

試試這個:

fd_set set; 
timeval timeout; 

while(1){ 
    FD_ZERO(&set); 
    FD_SET(serversock, &set); 

    timeout.tv_sec = 2; 
    timeout.tv_usec = 0; 

    printf("%s","Waiting on select\n"); 

    int ret = select(serversock+1, &set, NULL, NULL, &timeout); 

    if (ret==0){ 
     printf("timeout "); 
    } 

    else if (ret==-1){ 
     printf("Error occured\n"); 
     exit(0); 
    } 

    else if (ret>0){ //socket ready for reading 
     ... = accept(serversock, ...); 
     printf("Client connected\n"); 
    } 
} 

或者:

fd_set set; 
timeval timeout; 
int max_fd = 0; 

while(1){ 
    FD_ZERO(&set); 

    FD_SET(serversock, &set); 
    max_fd = serversock; 

    // FD_SET() other sockets and updating max_fd as needed... 

    timeout.tv_sec = 2; 
    timeout.tv_usec = 0; 

    printf("%s","Waiting on select\n"); 

    int ret = select(max_fd+1, &set, NULL, NULL, &timeout); 

    if (ret==0){ 
     printf("timeout "); 
    } 

    else if (ret==-1){ 
     printf("Error occured\n"); 
     exit(0); 
    } 

    else if (ret>0){ //socket(s) ready for reading 
     for (u_int i = 0; i < set.fd_count; ++i){ 
      ... = accept(set.fd_array[i], ...); 
      printf("Client connected\n"); 
     } 
    } 
}