сокет таймаута: работает, но почему и как, в основном, функция select ()? - PullRequest
0 голосов
/ 04 августа 2011

Вот часть кода, который я сейчас использую.

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;

Есть ли способ реализовать этот псевдокод, существуют ли эти флаги?

РЕДАКТИРОВАТЬ: Кроме того, почему sockfd + 1 в функции выбора в приведенном выше коде?Почему один добавляется к нему?

1 Ответ

1 голос
/ 04 августа 2011

Прочтите руководство: man 2 select:

  1. nfds is the highest-numbered file descriptor in any of the three sets, plus 1., поэтому sockfd + 1.
  2. select() возвращает количество дескрипторов, которые инициируют запрошенное событие. Дается только один дескриптор, поэтому select может возвращать самое большее 1.
  3. То есть, если через 3 секунды после заданного тайм-аута ничего не произойдет, select() не вернет 1, поэтому вы считаете его тайм-аутом. Случай ошибки -1 не обрабатывается.
...