在非阻塞套接字连接中,select() 始终返回 1

发布于 2024-11-04 15:17:38 字数 1515 浏览 5 评论 0原文

我有这个代码段,旨在使用套接字连接连接到服务器。但是,如果它无法在一定时间内连接到服务器,我希望它停止尝试。我尝试使用这个非阻塞套接字和 select 命令来执行此操作,但 select 始终返回 1,表明当我给它的地址处不存在任何内容时,服务器存在。有什么想法吗?

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\n", strerror(errno));
        return(0);
    }

    int x = 0;

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

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

    int retVal = select(s+1, &fdset, NULL, NULL, &tv);
    printf("retVal: %i\n", 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\n");

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


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

    return s;
}

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\n", strerror(errno));
        return(0);
    }

    int x = 0;

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

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

    int retVal = select(s+1, &fdset, NULL, NULL, &tv);
    printf("retVal: %i\n", 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\n");

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


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

    return s;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我只土不豪 2024-11-11 15:17:38

您需要检查套接字是否已准备好写入(select 的第二个 fd_set * 参数),而不是读取(第一个)。

You need to check whether the socket is ready for writing (the second fd_set * argument to select), not reading (the first one).

泅渡 2024-11-11 15:17:38

我发现的一个问题是,在创建套接字之前,您将 s 粘贴到 fdset 中。您需要

FD_SET(s, &fdset);

在创建套接字后执行以下操作,因为 s 只是一个整数,因此在调用 socket() 之前不会是正确的值。

编辑

像这样:

.
.
.
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\n", strerror(errno));
    return(0);
}    

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

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\n", strerror(errno));
    return(0);
}    

FD_ZERO(&fdset);
FD_SET(s, &fdset); // don't put socket in set until it is actually created 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文