Чтение онлайн

на главную

Жанры

UNIX: разработка сетевых приложений
Шрифт:

Чтобы решить эту проблему, нужно вызывать функцию

select
для проверки на наличие исключительной ситуации только после того, как будут приняты все обычные данные. В листинге 24.4 показана модифицированная версия принимающей программы из листинга 24.3. В этой версии описанный сценарий обрабатывается корректно.

Листинг 24.4. Модификация программы, приведенной в листинге 24.3. Функция select применяется для проверки исключительной ситуации корректным образом

//oob/tcprecv03.c

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

4 {

5 int listenfd, connfd, n, justreadoob = 0;

6 char buff[100];

7 fd_set rset, xset;

8 if (argc == 2)

9 listenfd = Tcp_listen(NULL, argv[1], NULL);

10 else if (argc == 3)

11 listenfd = Tcp_1isten(argv[1], argv[2], NULL);

12 else

13 err_quit("usage: tcprecv03 [ <host> ] <port#>");

14 connfd = Accept(listenfd, NULL, NULL);

15 FD_ZERO(&rset);

16 FD_ZERO(&xset);

17 for (;;) {

18 FD_SET(connfd, &rset);

19 if (justreadoob == 0)

20 FD_SET(connfd, &xset);

21 Select(connfd + 1, &rset, NULL, &xset, NULL);

22 if (FD_ISSET(connfd, &xset)) {

23 n = Recv(connfd, buff, sizeof(buff) - 1, MSG_OOB);

24 buff[n] = 0; /*
завершающий нуль */

25 printf("read %d OOB byte: %s\n", n, buff);

26 justreadoob = 1;

27 FD_CLR(connfd, &xset);

28 }

29 if (FD_ISSET(connfd, &rset)) {

30 if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {

31 printf("received EOF\n");

32 exit(0);

33 }

34 buff[n] = 0; /* завершающий нуль */

35 printf("read %d bytes: %s\n", n, buff);

36 justreadoob = 0;

37 }

38 }

39 }

5
Мы объявляем новую переменную с именем
justreadoob
, которая указывает, какие данные мы считываем — внеполосные
или обычные. Этот флаг определяет, нужно ли вызывать функцию
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
). Отметка внеполосных данных часто используется для того, чтобы принимающий процесс мог интерпретировать получаемые данные специальным образом до тех пор, пока он не дойдет до этой отметки.

Пример: особенности отметки внеполосных данных

Поделиться:
Популярные книги

Камень

Минин Станислав
1. Камень
Фантастика:
боевая фантастика
6.80
рейтинг книги
Камень

Огненный князь 4

Машуков Тимур
4. Багряный восход
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Огненный князь 4

Путь Чести

Щукин Иван
3. Жизни Архимага
Фантастика:
фэнтези
боевая фантастика
6.43
рейтинг книги
Путь Чести

Неудержимый. Книга XIX

Боярский Андрей
19. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XIX

Физрук 2: назад в СССР

Гуров Валерий Александрович
2. Физрук
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Физрук 2: назад в СССР

Камень. Книга шестая

Минин Станислав
6. Камень
Фантастика:
боевая фантастика
7.64
рейтинг книги
Камень. Книга шестая

Para bellum

Ланцов Михаил Алексеевич
4. Фрунзе
Фантастика:
попаданцы
альтернативная история
6.60
рейтинг книги
Para bellum

Девятое правило дворянина

Герда Александр
9. Истинный дворянин
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Девятое правило дворянина

Делегат

Астахов Евгений Евгеньевич
6. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Делегат

Шериф

Астахов Евгений Евгеньевич
2. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
6.25
рейтинг книги
Шериф

Мимик нового Мира 14

Северный Лис
13. Мимик!
Фантастика:
юмористическое фэнтези
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 14

Черный Маг Императора 9

Герда Александр
9. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 9

Темный Лекарь 4

Токсик Саша
4. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 4

Возвышение Меркурия. Книга 14

Кронос Александр
14. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 14