2013-06-12 125 views
1

我有這個代碼的問題:在TCP套接字超時選擇

FD_ZERO(&cset); 
FD_SET(s, &cset); 

tval.tv_sec = TIMEOUT; 
tval.tv_usec = 0; 

n = select(FD_SETSIZE, &cset, NULL, NULL, &tval); 

if (n==-1) { 
    printf(" select() failed \n"); 
    exit(-1); 
} 
if (n>0) { 
    check_control = connect(s,(struct sockaddr*) 
    &indirizzo_remoto,sizeof(indirizzo_remoto)); 

    if (check_control == -1) { 
     printf("Errore connect()\n"); 
    } 

}else{ 
    printf("Timeout. I'll shutdown the client"); 
    exit(-1); 
} 

我想插入的連接超時,但它不工作:

我使用正確的IP地址,服務器的端口號,但連接超時。

非常感謝您的幫助。

+0

是,通過telnet它的作品! – user2467899

+0

這是錯誤的嗎?因爲我想這就是服務器關閉,當客戶端嘗試連接它,如果它需要30秒客戶端停止並關閉插座 – user2467899

+0

(對不起英語)....我想,如果服務器/當客戶端嘗試連接到它 – user2467899

回答

2

您正在使用select()檢查給定的套接字是否在可讀的狀態中,然後在該套接字上調用connect()。這將永遠不會工作。未連接的TCP套接字永遠不會處於可讀狀態,並且不能與select()一起使用,直到首先調用connect()

實現了connect()叫了暫停,唯一的辦法就是把插座成非阻塞模式第一(套接字默認攔截),然後調用connect()(該方法返回一個EINPROGRESS錯誤如果套接字嘗試連接),然後用select()等待插座進入狀態,表示連接成功,或錯誤狀態,指示連接失敗。

試試這個:

fcntl(s, F_SETFL, O_NONBLOCK); 

或者:

flags = 1; 
ioctl(s, FIOBIO, &flags); 

根據您的平臺。

然後:

check_control = connect(s, (struct sockaddr*) &indirizzo_remoto, sizeof(indirizzo_remoto)); 
if (check_control == -1) 
{ 
    if (errno != EINPROGRESS) 
    { 
     printf("Errore connect()\n"); 
     exit(-1); 
    } 

    FD_ZERO(&wset); 
    FD_SET(s, &wset); 

    FD_ZERO(&eset); 
    FD_SET(s, &eset); 

    tval.tv_sec = TIMEOUT; 
    tval.tv_usec = 0; 

    n = select(s+1, NULL, &wset, &eset, &tval); 
    if (n == -1) 
    { 
     printf(" select() failed \n"); 
     exit(-1); 
    } 

    if (n == 0) 
    { 
     printf("Timeout. I'll shutdown the client"); 
     exit(-1); 
    } 

    if (FD_ISSET(s, &eset)) 
    { 
     printf("Cannot connect. I'll shutdown the client"); 
     exit(-1); 
    } 

    int err = -1; 
    getsockopt(s, SOL_SOCKET, SO_ERROR, &err, sizeof(err)); 
    if (err != 0) 
    { 
     printf("Cannot connect. I'll shutdown the client"); 
     exit(-1); 
    } 
} 

// connected...