非阻塞socket 的连接

本文详细介绍了如何在C语言中实现非阻塞socket的连接,包括两种方案:通过FIONBIO设置非阻塞模式和利用select函数监控连接状态。文章讨论了非阻塞connect在系统进行TCP三路握手时的处理,以及其在多连接并发和缩短超时时间上的应用。此外,还提供了详细的示例代码和注意事项,如在连接成功或失败时如何判断,以及在连接被中断时的处理策略。
摘要由CSDN通过智能技术生成

 http://blog.csdn.net/ruixj/archive/2007/08/23/1756440.aspx

 

方案1:
int connect_socket_timeout(int sockfd,char *dest_host, int port, int timeout)
{
    struct sockaddr_in address;
    struct in_addr inaddr;
    struct hostent *host;
    int  err, noblock=1 , connect_ok=0, begin_time=time(NULL);
    log_debug("connect_socket to %s:%d/n",dest_host,port);                                                          
    if (inet_aton(dest_host, &inaddr))
    {       
//        log_debug("inet_aton ok now gethostbyaddr %s/n",dest_host);
        memcpy(&address.sin_addr, &inaddr, sizeof(address.sin_addr));
    }
    else
    {
        log_debug("inet_aton fail now gethostbyname %s /n",dest_host);
        host = gethostbyname(dest_host);
        if (!host) {
                        /* We can't find an IP number */
            log_error("error looking up host  %s : %d/n",dest_host,errno);
            return -1;
        }                                                               
        memcpy(&address.sin_addr, host->h_addr_list[0], sizeof(address.sin_addr));
    }
    address.sin_family = AF_INET;
    address.sin_port = htons(port);
    /* Take the first IP address associated with this hostname */
        ioctl(sockfd,FIONBIO,&noblock);
   
/** connect until timeout */
/*
EINPROGRESS                A nonblocking socket connection cannot be completed immediately.
EALREADY                The socket is nonblocking and a        previous connection attempt has not been completed.
EISCONN                        The socket is already connected.
*/
                if (connect(sockfd, (struct sockaddr *) &address, sizeof(address)) < 0)
                {
                        err = errno;
                        if (err != EINPROGRESS)
                        {
                                log_error("connect = %d connecting to host %s/n", err,dest_host);
                        }
                        else
                        {
//                                log_notice("connect pending, return %d /n", err);
                                while (1) /* is noblocking connect, check it until ok or timeout */
                                {
                                        connect(sockfd, (struct sockaddr *) &address, sizeof(address));
                                        err = errno;
                                        switch (err)
                                        {
                                                case EISCONN:   /* connect ok */
                                                        connect_ok = 1;
                                                        break;
                                                case EALREADY:  /* is connecting, need to check again */
//                                                        log_info("connect again return EALREADY check again.../n");
                                                        usleep(50000);
                                                        break;
//                                                default:   /* failed, retry again ? */
                                                        log_error("connect fail err=%d /n",err);
//                                                        connect_ok = -1;
//                                                        break;
                                        }
                                        if (connect_ok==1)
                                        {
//                                            log_info ("connect ok try time =%d /n", (time(NULL) - begin_time) );
                                            break;
                                        }
                                        if (connect_ok==-1)
                                        {
                                            log_notice ("connect failed try time =%d /n", (time(NULL) - begin_time) );
                                            break;
                                        }
                                        if ( (timeout>0) && ((time(

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值