套接字超时:它有效,但为什么以及如何,主要是select()函数?

时间:2011-08-03 20:00:17

标签: c sockets select timeout

以下是我现在使用的代码的一部分。

fd_set fdset;
struct timeval tv;
int flags = fcntl(sockfd, F_GETFL);    
fcntl(sockfd, F_SETFL, O_NONBLOCK);

connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));

FD_ZERO(&fdset);
FD_SET(sockfd, &fdset);
tv.tv_sec = 3;          
tv.tv_usec = 0;

if (select(sockfd + 1, NULL, &fdset, NULL, &tv) == 1)
{
    int so_error;
    socklen_t len = sizeof so_error;
    getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len);
    if (so_error == 0) {
        cout << " - CONNECTION ESTABLISHED\n";
    }
} else
{
    cout << " - TIMEOUT\n";
    exit(-1);
}

我不清楚select()函数是如何工作的,这里伪代码是我真正想做的事情,

    bool showOnce = true;

    connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) 
    while(stillConnecting) /*Some kind of flag of connection status*/
    {
        if(showOnce)
        {
            showOnce = false;
            cout << "Connecting";
        }
    }

    if(connected) /*Another possible flag if it exists*/
        return true;
    else
        return false;

无论如何都要实现这个伪代码,这些标志是否存在?

编辑:为什么上面代码中的select函数中的sockfd + 1?为什么要添加一个?

1 个答案:

答案 0 :(得分:1)

阅读手册:man 2 select

  1. nfds is the highest-numbered file descriptor in any of the three sets, plus 1.,这就是sockfd + 1
  2. 的原因
  3. select()返回触发请求事件的描述符数。只给出了一个描述符,因此select最多可以返回1
  4. 因此,如果3秒后,给定的超时,没有任何反应,select()不会返回1,所以您认为它是超时。不处理错误-1的情况。