在非阻塞套接字连接,请选择()始终返回1 [英] In a non blocking socket connect, select() always returns 1

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

问题描述

我有一个用于连接到使用套接字连接服务器,则此code段。然而,如果它不能在一定的时间内连接到服务器我想它停止尝试。我试着做这本非阻塞套接字和选择命令,但选择总是返回1,指示服务器没事的时候存在于我给它的地址是否存在。任何想法?

  SOCKET tcp_client(字符* hname,字符* SNAME){
    FD_SET fdset;
    结构SOCKADDR_IN同行;
    插座S;
    FD_ZERO(安培; fdset);
    // FD_SET(STDIN,&安培; fdset);
    FD_SET(S,&放大器; fdset);
    错误号= 1;
    timeval结构电视;
    tv.tv_sec = 15;
    SET_ADDRESS(hname,SNAME,&安培;同行,TCP);
    S =插座(AF_INET,SOCK_STREAM,0);    INT N = 1;
    的fcntl(S,F_SETFL,O_NONBLOCK);    如果(!isvalidsock(多个))
    {
        的printf(插座调用失败:%S \\ n字符串错误(错误));
        返回(0);
    }    INT X = 0;    INT状态=连接(S,(结构sockaddr *)及同行,的sizeof(同行));    如果(状态℃,){
        的printf(状态:%I \\ N,地位);
    }    INT retVal的选择=(S + 1,&安培; fdset,NULL,NULL,&安培;电视);
    的printf(retVal的:%I \\ N,retVal的);    如果(retVal的== 1){
        INT SO_ERROR;
        socklen_t的SLEN = sizeof的SO_ERROR;
        用getsockopt(S,SOL_SOCKET,SO_ERROR,&安培; SO_ERROR,&安培; SLEN);
        如果(SO_ERROR == 0){
            的printf(工\\ n);            X = 1;
        }其他{
            的printf(失败\\ n);
            X = 0;
        }
    }其他{
        的printf(noSocks的\\ n);
    }
    如果(X == 0)
    {
        的printf(连接失败:%S \\ n字符串错误(错误));
        L(libOnexc:连接到插座失败);
        接近(S);
        返回(0);
    }    返回S;
}


解决方案

有一个问题我看到的是,你坚持■在fdset已创建的套接字之前。你需要做的。

  FD_SET(S,放大器; fdset);

您已经创建套接字之后,因为s是只是一个整数,所以不会是正确的值,直到后调用插座()。

修改

这样的:

 


插座S;
错误号= 1;
timeval结构电视;
tv.tv_sec = 15;
SET_ADDRESS(hname,SNAME,&安培;同行,TCP);
S =插座(AF_INET,SOCK_STREAM,0);INT N = 1;
的fcntl(S,F_SETFL,O_NONBLOCK);如果(!isvalidsock(多个))
{
    的printf(插座调用失败:%S \\ n字符串错误(错误));
    返回(0);
}FD_ZERO(安培; fdset);
FD_SET(S,&放大器; fdset); //不要把插座集,直到它实际上是创建

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;
}

解决方案

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 

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

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