Проверить количество доступных буферных символов в файловом дескрипторе - PullRequest
1 голос
/ 06 августа 2020

Как мне проверить, сколько доступных символов находится в буфере в дескрипторе файла сокета?

Я хочу отложить чтение байтов из сокета до тех пор, пока не будет доступно не менее 8 байтов (для длины следующего сообщение). Я использую select() для ожидания входящих данных. Когда вызывается обработчик чтения для сокета, я хочу, чтобы он просто возвращался без чтения, если доступно менее 8 байт.

Будет ли сокет когда-либо доступен для чтения, но только для менее 8 байтов?

Существует ли системный вызов Linux, который может получить, сколько байтов доступно для чтения из сокета, не читая их на самом деле?

1 Ответ

3 голосов
/ 07 августа 2020

Вы можете использовать ioctl() с запросом FIONREAD (SIOCINQ).

Из tcp (7) man-страницы:

Следующие вызовы ioctl (2) возвращают информацию в value. Правильный синтаксис:

int value;
error = ioctl(tcp_socket, ioctl_type, &value);

ioctl_type является одним из следующих:

SIOCINQ Возвращает количество непрочитанных данных в очереди в приемном буфере. Сокет не должен находиться в состоянии LISTEN, иначе будет возвращена ошибка (EINVAL). SIOCINQ определяется в . В качестве альтернативы вы можете использовать синоним FIONREAD, определенный в .

...

Из udp (7) man-страницы:

Доступ к этим ioctl можно получить с помощью ioctl (2) . Правильный синтаксис:

int value;
error = ioctl(udp_socket, ioctl_type, &value);

FIONREAD (SIOCINQ) Получает указатель на целое число в качестве аргумента. Возвращает размер следующей ожидающей датаграммы в виде целого числа в байтах или 0, если нет ожидающих датаграмм. Предупреждение: Используя FIONREAD, невозможно отличить guish случай, когда дейтаграмма не ожидает обработки, от случая, когда следующая ожидающая датаграмма содержит нулевые байты данных. Безопаснее использовать select (2) , poll (2) или epoll (7) , чтобы различать guish эти случаи.

...

Сокет будет находиться в читаемом состоянии, пока его буфер приема содержит не менее 1 байта в TCP или 1 дейтаграмму в UDP. Или, в случае TCP, если соединение было корректно закрыто одноранговым узлом (был получен пакет FIN), в этом случае последующее чтение будет сообщать 0 байтов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...