在非阻塞套接字连接中,select() 总是返回 1 [英] In a non blocking socket connect, select() always returns 1

查看:45
本文介绍了在非阻塞套接字连接中,select() 总是返回 1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个代码段,旨在使用套接字连接连接到服务器.但是,如果它在一定时间内无法连接到服务器,我希望它停止尝试.我试图用这个非阻塞套接字和 select 命令来做到这一点,但 select 总是返回 1 表示服务器存在,当我给它的地址不存在任何东西时.有什么想法吗?

SOCKET tcp_client( char *hname, char *sname ) {fd_set fdset;struct sockaddr_in 对等体;插座;FD_ZERO(&fdset);//FD_SET(STDIN, &fdset);FD_SET(s, &fdset);错误号=1;struct timeval 电视;tv.tv_sec = 15;set_address( hname, sname, &peer, "tcp" );s = 套接字(AF_INET,SOCK_STREAM,0);整数 n = 1;fcntl(s, F_SETFL, O_NONBLOCK);如果(!isvalidsock(s)){printf("套接字调用失败:%s
", strerror(errno));返回(0);}整数 x = 0;int status = connect(s, (struct sockaddr *)&peer, sizeof(peer));如果(状态<0){printf("状态:%i
", 状态);}int retVal = select(s+1, &fdset, NULL, NULL, &tv);printf("retVal: %i
", retVal);如果(retVal == 1){int so_error;socklen_t slen = sizeof so_error;getockopt(s, SOL_SOCKET, SO_ERROR, &so_error, &slen);如果(so_error == 0){printf("工作
");x = 1;} 别的 {printf("失败
");x = 0;}} 别的 {printf("noSocks
");}如果 (x ==0 ){printf("连接失败:%s
", strerror(errno));L("libOnexc: 连接套接字失败");关闭;返回(0);}返回 s;}

解决方案

我看到的一个问题是您在创建套接字之前将 s 粘在 fdset 中.你需要这样做

FD_SET(s, &fdset);

在创建套接字之后,因为 s 只是一个整数,因此在调用 socket() 之前不会是正确的值.

编辑

像这样:

<预><代码>...插座;错误号=1;struct timeval 电视;tv.tv_sec = 15;set_address( hname, sname, &peer, "tcp" );s = 套接字(AF_INET,SOCK_STREAM,0);整数 n = 1;fcntl(s, F_SETFL, O_NONBLOCK);如果(!isvalidsock(s)){printf("套接字调用失败:%s ", strerror(errno));返回(0);}FD_ZERO(&fdset);FD_SET(s, &fdset);//在实际创建之前不要将套接字放入 set

I have this code segment that is designed to connect to a server using a socket connection. However if it can not connect to the server within a certain amount of time I would like it to stop trying. I tried to do this with this nonblocking socket and the select command but select is always returning 1 indicating that the server exists when nothing exists at the address I give it. Any Ideas?

SOCKET tcp_client( char *hname, char *sname )  {    
    fd_set fdset;
    struct sockaddr_in peer;
    SOCKET s;
    FD_ZERO(&fdset);
    // FD_SET(STDIN, &fdset);
    FD_SET(s, &fdset);
    errno=1;
    struct timeval tv;
    tv.tv_sec = 15;
    set_address( hname, sname, &peer, "tcp" );
    s = socket( AF_INET, SOCK_STREAM, 0 );

    int n = 1;
    fcntl(s, F_SETFL, O_NONBLOCK);

    if ( !isvalidsock( s ) )
    {
        printf("Socket Call Failed: %s
", strerror(errno));
        return(0);
    }

    int x = 0;

    int status = connect( s, ( struct sockaddr * )&peer, sizeof( peer ) );

    if(status < 0) {
        printf("Status: %i
", status); 
    }

    int retVal = select(s+1, &fdset, NULL, NULL, &tv);
    printf("retVal: %i
", retVal);

    if (retVal == 1) {
        int so_error;
        socklen_t slen = sizeof so_error;
        getsockopt(s, SOL_SOCKET, SO_ERROR, &so_error, &slen);
        if (so_error == 0) {
            printf("work
");

            x =1;
        } else {
            printf("fail
");
            x = 0;
        }
    } else {     
        printf("noSocks
"); 
    }


    if (x ==0 )
    {
        printf("Connect Failed: %s
", strerror(errno));
        L("libOnexc: Connect to socket failed");
        close(s);
        return(0);
    } 

    return s;
}

解决方案

One problem I see is that you stick s in the fdset before you have created the socket. You need to do the

FD_SET(s, &fdset);

after you've created the socket because s is just an integer and so will not be the right value until after the call to socket().

EDIT

Like this:

.
.
.
SOCKET s;
errno=1;
struct timeval tv;
tv.tv_sec = 15;
set_address( hname, sname, &peer, "tcp" );
s = socket( AF_INET, SOCK_STREAM, 0 );

int n = 1;
fcntl(s, F_SETFL, O_NONBLOCK);

if ( !isvalidsock( s ) )
{
    printf("Socket Call Failed: %s
", strerror(errno));
    return(0);
}    

FD_ZERO(&fdset);
FD_SET(s, &fdset); // don't put socket in set until it is actually created 

这篇关于在非阻塞套接字连接中,select() 总是返回 1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆