读书笔记:非阻塞connect

函数原型:
<pre name="code" class="cpp">#include <sys/socket.h>
int connect(int socket, const struct sockaddr *address,socklen_t address_len)
成功:返回0  失败:返回-1

 

1.如果没有设置O_NONBLOCK状态,并且不能立即建立连接,将一直阻塞。如果在此过程中被信号中断,connect将返回失败,并设置errno 为 EINTR,但连接请求此时不会退出,连接将会异步建立。

2.如果设置了O_NONBLOCK,并且不能立即简历连接,连接将返回失败,并设置errno 为EINPROGRESS,连接请求不会中断,连接将会异步建立。如果在连接没有建立完成的状态下重新调用connect连接同一个socket将返回失败,并设置errno 为EALREADY。

非阻塞connect成功或失败判断方式:

1.调用connect返回0,连接成功,返回。

否则

2.返回-1时,如果errno不等于EINPROGRESS,连接失败。

否则

3.通过select poll epoll监听描述符事件,比如select,如果select返回值<=0表示select失败或超时,连接失败。

或 描述符不可写,连接失败。(connect成功时,描述符可写;connect失败时,描述符可读可写)

4.通过getsockopt获取描述符上的错误,如果错误号不是0,表示连接失败。

否则

5.连接成功

部分源码示意:(摘自Linux高性能服务器编程)

    // 设置非阻塞
    int fdopt = setnonblocking( sockfd );
    ret = connect( sockfd, ( struct sockaddr* )&address, sizeof( address ) );
    // 连接成功
    if ( ret == 0 )
    {
        printf( "connect with server immediately\n" );
        fcntl( sockfd, F_SETFL, fdopt );
        return sockfd;
    }
    // 连接失败
    else if ( errno != EINPROGRESS )
    {
        printf( "unblock connect not support\n" );
        return -1;
    }

    fd_set readfds;
    fd_set writefds;
    struct timeval timeout;

    FD_ZERO( &readfds );
    FD_SET( sockfd, &writefds );

    timeout.tv_sec = time;
    timeout.tv_usec = 0;

    // 监听描述符事件
    ret = select( sockfd + 1, NULL, &writefds, NULL, &timeout );
    // select错误或超时
    if ( ret <= 0 )
    {
        printf( "connection time out\n" );
        close( sockfd );
        return -1;
    }
    // 描述符不可写
    if ( ! FD_ISSET( sockfd, &writefds  ) )
    {
        printf( "no events on sockfd found\n" );
        close( sockfd );
        return -1;
    }

    int error = 0;
    socklen_t length = sizeof( error );
    // 获取错误码
    if( getsockopt( sockfd, SOL_SOCKET, SO_ERROR, &error, &length ) < 0 )
    {
        printf( "get socket option failed\n" );
        close( sockfd );
        return -1;
    }
    // 错误码不等于0,失败
    if( error != 0 )
    {
        printf( "connection failed after select with the error: %d \n", error );
        close( sockfd );
        return -1;
    }

    // 连接成功
    // TODO


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值