для проверки на наличие исключительной ситуации только после того, как будут приняты все обычные данные. В листинге 24.4 показана модифицированная версия принимающей программы из листинга 24.3. В этой версии описанный сценарий обрабатывается корректно.
Листинг 24.4. Модификация программы, приведенной в листинге 24.3. Функция select применяется для проверки исключительной ситуации корректным образом
, которая указывает, какие данные мы считываем — внеполосные
или обычные. Этот флаг определяет, нужно ли вызывать функцию
select
для проверки на наличие исключительной ситуации.
26-27
Когда мы устанавливаем флаг
justreadoob
, мы также должны выключить бит соответствующего дескриптора в наборе для проверки исключительных ситуаций.
Теперь программа работает так, как мы ожидали.
24.3. Функция sockatmark
С приемом внеполосных данных всегда связана так называемая отметка внеполосных данных( out-of-bandmark). Это позиция в потоке обычных данных на стороне отправителя, соответствующая тому моменту; когда посылающий процесс отправляет байт, содержащий внеполосные данные. Считывая данные из сокета, принимающий процесс путем вызова функции
sockatmark
определяет, находится ли он в данный момент на этой отметке.
#include <sys/socket.h>
int sockatmark(int sockfd);
Возвращает: 1, если находится на отметке внеполосных данных: 0, если не на отметке; -1 в случае ошибки
ПРИМЕЧАНИЕ
Эта функция появилась в POSIX. Разработчики стандарта POSIX стремятся заменить отдельными функциями все вызовы ioctl с различными параметрами.
В листинге 24.5 показана реализация этой функции с помощью поддерживаемого в большинстве систем параметра
SIOCATMARK
функции
ioctl
.
Листинг 24.5. Функция sockatmark реализована с использованием функции ioctl
//lib/sockatmark.c
1 #include "unp.h"
2 int
3 sockatmark(int fd)
4 {
5 int flag;
6 if (ioctl(fd, SIOCATMARK, &flag) < 0)
7 return (-1);
8 return (flag != 0 ? 1 : 0);
9 }
Отметка внеполосных данных применима независимо от того, как принимающий процесс получает внеполосные данные: вместе с обычными данными (параметр сокета
SO_OOBINLINE
) или отдельно (флаг
MSG_OOB
). Отметка внеполосных данных часто используется для того, чтобы принимающий процесс мог интерпретировать получаемые данные специальным образом до тех пор, пока он не дойдет до этой отметки.