C socket: 关于connect超时设置_老杨风子_新浪博客

使用阻塞的socket, 可以设置读写超时,
    struct timeval tv_timeout; 
    tv_timeout.tv_sec = 60; 
    tv_timeout.tv_usec = 0; 
    if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (void *) &tv_timeout, sizeof(struct timeval)) < 0) { 
        perror("setsockopt"); 
    } 
    tv_timeout.tv_sec = 60; 
    tv_timeout.tv_usec = 0; 
    if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (void *) &tv_timeout, sizeof(struct timeval)) < 0) { 
        perror("setsockopt"); 
    } 


但是这个不会影响connect.
如何设置connect超时呢, 通过信号alarm? 感觉不是一个好的办法.比较好的办法是通过select或者poll判断超时.
首先设置socket fd为非阻塞, connect判断返回值, 如果返回0, 说明connect成功, 如果返回值等于-1并且错误的errno为EINPROGRESS时调用select或者poll判断socket fd的可写状态, 通过select或者poll的超时设置来判断是否超时.
man page是这么写的

    EINPROGRESS
    The socket is non-blocking and the connection cannot be com-
    pleted immediately. It is possible to select(2) or poll(2) for
    completion by selecting the socket for writing. After select(2)
    indicates writability, use getsockopt(2) to read the SO_ERROR
    option at level SOL_SOCKET to determine whether connect() com-
    pleted successfully (SO_ERROR is zero) or unsuccessfully
    (SO_ERROR is one of the usual error codes listed here, explain-
    ing the reason for the failure).

我这英语也不行,这个也看不懂,百度翻译一下吧。
下边是示例代码:
    int opt = 1; 
    //set non-blocking 
    if (ioctl(sockfd, FIONBIO, &opt) < 0) { 
        close(sockfd); 
        perror("ioctl"); 
        exit(0); 
    } 
     
    if (connect(sockfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) == -1) { 
        if (errno == EINPROGRESS) { 
            int error; 
            int len = sizeof(int); 
            tv_timeout.tv_sec  = 60;  
            tv_timeout.tv_usec = 0; 
            FD_ZERO(&set); 
            FD_SET(sockfd, &set); 
            if(select(sockfd + 1, NULL, &set, NULL, &tv_timeout) > 0) { 
                getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len); 
                if(error != 0) { 
                    close(sockfd); 
                    exit(0); 
                } 
            } else { //timeout or select error 
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值