2013-06-12 89 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...