2013-05-08 130 views
0

我已經設置了一個非阻塞連接呼叫的超時,當連接嘗試到一個不會響應的地址時正確超時。 但是,當連接被目的地拒絕時,它似乎不會返回連接被拒絕的呼叫。非阻塞連接呼叫不返回連接拒絕

int x = fcntl(iSock,F_GETFL, 0); 
fcntl(iSock,F_SETFL, x | O_NONBLOCK); 

fd_set writeFD; 

FD_ZERO(&writeFD); 
FD_SET(iSock, &writeFD); 

timeval timeout; 
timeout.tv_sec = 30; 
timeout.tv_usec = 0; 

errno = 0; 

if ((iStat = connect(iSock, (struct sockaddr *)&addr, sizeof(addr))) < 0) 
{ 
    if(errno == EINPROGRESS) 
    { 
     if(int retval = (select (iSock+1, (fd_set *)NULL, &writeFD, (fd_set *)NULL, (struct timeval *)(&timeout)) > 0)) 
     { 
      socklen_t len = 0; 
      int error = 0; 
      if (getsockopt(iSock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) 
       return (-1); 

      if (error == EINPROGRESS) 
      { 
       close(iSock); 
       errno = error; 
       return (-1); 
      } 
      else 
      { 
       printf("Connected \n"); 
       return 0; 
      } 
     } 
     else 
     { 
      printf("Not Connected - %d\n", errno); 
      close(iSock); 
      return iStat; 
     } 
    } 
    else 
    { 
     close(iSock); 
     return iStat; 
    } 
} 

從連接調用,它似乎總是返回EINPROGRESS,然後選擇通話將返回> 0誤差設置爲0

當我將其更改爲阻塞連接電話,我得到的立即從connect調用返回CONNECTIONREFUSED的代碼。

+0

請注意,這些書籍用來代替'getsockopt(...,SO_ERROR,...)'執行第二個'connect()'調用;很久以前。 – EJP 2013-05-09 00:11:22

回答

1

socklen_t len = 0;是不正確的。 這需要設置爲 socklen_t len = sizeof(int);

設置固定的問題,這個值和正確的返回碼(CONNREFUSED)從選擇呼叫設置

+0

爲什麼sizeof(int)?聽起來很愚蠢。 – 2013-11-09 17:05:03

0

我認爲socklen_t len = sizeof(error);優於sizeof(int)
這是一樣的結果。