判断tcp 是否正常连接

int test_tcp_connect(const char* dst, unsigned short port)
{
    struct sockaddr_in addr;
    int flags;
    fd_set writefds;
    int nfds;
    struct timeval timeout;
    int result;
    int tcp_sd;

    if(NULL == dst)
        return -1;

    tcp_sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if(tcp_sd < 0)
        return -2;

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = net_inet_aton(dst);
    addr.sin_port = htons(port);
    printf("hilink tcp connect ip: %s port = %d\r\n",dst,port);
    /*Set as nonblocking*/
    flags = fcntl(tcp_sd, F_GETFL, 0);
    fcntl(tcp_sd, F_SETFL, flags | O_NONBLOCK);

    int    reuse = 1;
    if(setsockopt(tcp_sd, SOL_SOCKET, SO_REUSEADDR,(const char *) &reuse, sizeof( reuse ) ) != 0 )
    {
        close(tcp_sd);
        printf("tcp set SO_REUSEADDR failed\n");
        return -2;
    }
    if(connect(tcp_sd, (const struct sockaddr_in *)&addr, sizeof(addr)) != 0 \
        && errno != EINPROGRESS)
    {
        printf("dna_connect failed %d\n", tcp_sd);
        goto err;
    }

    nfds = tcp_sd + 1;
    timeout.tv_sec = 3; //Waiting 2s to connect to tcp server
    timeout.tv_usec = 0;

    FD_ZERO(&writefds);
    FD_SET(tcp_sd, &writefds);

    result = select(nfds, NULL, &writefds, NULL, &timeout);

    //dna_printf("hilink  tcp Result %d %d\r\n", result, FD_ISSET(tcp_sd, &writefds));
    if(result == 0)
        goto err;
    else if(result > 0)
    {
        if(FD_ISSET(tcp_sd, &writefds))
        {
            int   error   =   0; 
            int   len   =   sizeof   (error);
            result = getsockopt(tcp_sd,SOL_SOCKET,SO_ERROR,&error,  &len);
            printf( "getsockopt fail,result  =%d error=%d\r\n",result,error);
            if(result   <   0)
            {
                printf( "getsockopt fail,connected  fail \n");
                goto err;
            }

            if(error != 0)
            {
                printf("error = %d , connected fail \r\n",error);
                goto err;
            }

            return tcp_sd;

        }
    }


err:
    close(tcp_sd);
    return -2;
}

1 要设置为非阻塞的模式,阻塞模式connect 大多数设计都是75s
2 通过select 判断等待套接字可读或可写,如果可以读或写;再通过 getsockopt 处理SO_ERROR,如果小于0,则连接失败,考虑不同平台的兼容性,(Berkeley getsockopt 返回为0,错误在码SO_ERROR里,Solaris 则会返回-1),所以还需要进一步判断错误码,具体可以参考书籍《UNIX网络编程卷1:套接字API(第三版) p352》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值