Почему, когда я добавляю POLLHUP как событие, WSAPoll возвращает ошибку (недопустимые аргументы)? - PullRequest
0 голосов
/ 04 апреля 2019

Я использую WSAPoll для своего проекта.Я использовал отслеживание событий POLLIN и POLLOUT.Все работало хорошо.Когда я добавляю POLLHUP в качестве события, WSAPoll возвращает ошибку 10022 (неверный аргумент).

Я не знаю, что не так, пожалуйста, подскажите, как это исправить: (

cc_qnt - количествоподключенных клиентов

        int ev_cnt = WSAPoll(pfd, cc_qnt + 1, 100);
        if (ev_cnt > 0) { 

            for (i = 0; i < cc_qnt; i++)  {   

                if (pfd[i].revents & POLLHUP) {      

                    // some code
                } 

                if (pfd[i].revents & POLLIN) {

                    // some code
                }
            } 

            if (pfd[cc_qnt].revents & POLLIN) { 

В этой части у нас есть новое соединение, готовое к принятию. Мы редактируем pfd[cc_qnt], добавляя новый сокет (возвращаемый accept) вместо прослушивающего сокета. Затем мы перераспределяем pfd с размером + 1,копирование предыдущих данных и добавление прослушивающего сокета в конце массива cc.

                int addrlen = sizeof(addr);
                cc[cc_qnt].s = accept(ls, (struct sockaddr*) &addr, &addrlen);
                cc[cc_qnt].ip = ntohl(addr.sin_addr.s_addr);
                cc[cc_qnt].sent_put = 0;
                cc[cc_qnt].c_cl_cn = 0;

                pfd[cc_qnt].fd = cc[i].s;
                pfd[cc_qnt].events = POLLIN | POLLOUT | POLLHUP;

                cc_qnt++;
                pfd = init_pfd(pfd, ls, cc_qnt);
            }   
        }   
        else if (ev_cnt < 0) {    

            exit(printf("\nprocess_events: WSAPoll, ev_cnt = %d, WSAGetLastError: %d \n", ev_cnt, WSAGetLastError()));
        }  

Все, что я изменил для отслеживания POLLHUP - добавление его бита в pfd [cc_qnt] .events и WSAPoll начал возвращать ошибку. Я ожидаю отслеживания POLLHUPсобытие.

1 Ответ

0 голосов
/ 06 апреля 2019

Согласно документации WSAPoll():

WSAEINVAL

Передан недопустимый параметр.Эта ошибка возвращается, если параметр fdarray содержит указатель NULL. Эта ошибка также возвращается, если в элементе events любой из структур WSAPOLLFD, указанных параметром fdarray при запросе статуса сокета , были указаны недопустимые флаги.Эта ошибка также возвращается, если ни один из сокетов, указанных в элементе fd любой из структур WSAPOLLFD, на которые указывает параметр fdarray, не был действительным.

А согласно WSAPOLLFD документации:

events

Тип: short

Набор флагов, указывающих тип запрашиваемого статуса. Это должно быть одно или несколько из следующих значений.

POLLPRI
Данные приоритета могут считываться без блокировки.Этот флаг не поддерживается поставщиком Microsoft Winsock.

POLLRDBAND
Данные диапазона приоритета (внеполосные) можно читать без блокировки.

POLLRDNORM
Нормальные данные можно читать без блокировки.

POLLWRNORM
Нормальные данные можно записывать без блокировки.

Флаг POLLIN определяется как комбинация POLLRDNORMи POLLRDBAND значения флага.Флаг POLLOUT определяется так же, как значение флага POLLWRNORM.

Таким образом, как вы можете видеть, POLLHUP не задокументирован как действительный флаг для ввода до WSAPoll().Действительно, он не соответствует ни одному из указанных выше флагов, определенных в winsock2.h:

/* Event flag definitions for WSAPoll(). */

#define POLLRDNORM  0x0100
#define POLLRDBAND  0x0200
#define POLLIN      (POLLRDNORM | POLLRDBAND)
#define POLLPRI     0x0400

#define POLLWRNORM  0x0010
#define POLLOUT     (POLLWRNORM)
#define POLLWRBAND  0x0020

#define POLLERR     0x0001
#define POLLHUP     0x0002
#define POLLNVAL    0x0004

POLLHUP, однако, задокументирован как флаг output в элементе reventsиз WSAPOLLFD:

revents

Тип: short

Набор флагов, которые по возвращении из вызова функции WSAPoll указывают нарезультаты запроса статуса.Это может быть комбинацией следующих флагов:

...

POLLHUP
Потоковое соединение было отключено или прервано.

...

Это соответствует использованию POLLHUP в poll() на * платформах nix:

POLLHUP
Повесить трубку ( возвращается только в revents; игнорируется в events).Обратите внимание, что при чтении из канала, такого как канал или сокет потока, это событие просто указывает, что узел закрыл свой конец канала.Последующие чтения из канала вернут 0 (конец файла) только после того, как все ожидающие данные в канале были использованы.

Итак, вам не нужно (а в Windows вы не можете)явно запросите POLLHUP, вы просто получите его бесплатно.

...