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

на главную - закладки

Жанры

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

Далее мы приводим простой пример, иллюстрирующий следующие две особенности отметки внеполосных данных:

1. Отметка внеполосных данных всегда указывает на один байт дальше конечного байта обычных данных. Это означает, что, когда внеполосные данные получены вместе с обычными, функция

sockatmark
возвращает 1, если следующий считываемый байт был послан с флагом
MSG_OOB
. Если параметр
SO_OOBINLINE
не включен (состояние по умолчанию), то функция
sockatmark
возвращает 1, когда следующий байт данных
является первым байтом, посланным следом за внеполосными данными.

2. Операция считывания всегда останавливается на отметке внеполосных данных [128, с. 519–520]. Это означает, что если в приемном буфере сокета 100 байт, но только 5 из них расположены перед отметкой внеполосных данных, то когда процесс выполнит функцию

read
, запрашивая 100 байт, возвратятся только 5 байт, расположенные до этой отметки. Эта вынужденная остановка на отметке позволяет процессу вызвать функцию
sockatmark
, которая определит, находится ли указатель буфера на отметке внеполосных данных.

В листинге 24.6 показана наша программа отправки. Она посылает три байта обычных данных, один байт внеполосных данных, а затем еще один байт обычных данных. Паузы между этими операциями отсутствуют.

В листинге 24.7 показана принимающая программа. В ней не используется ни функция

select
, ни сигнал
SIGURG
. Вместо этого в ней вызывается функция
sokatmark
, определяющая положение байта внеполосных данных.

Листинг 24.6. Программа отправки

//oob/tcpsen04.c

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

4 {

5 int sockfd;

6 if (argc != 3)

7 err_quit("usage: tcpsend04 <host> <port#>");

8 sockfd = Tcp_connect(argv[1], argv[2]);

9 Write(sockfd, "123", 3);

10 printf("wrote 3 bytes of normal data\n");

11 Send(sockfd, "4", 1, MSG_OOB);

12 printf("wrote 1 byte of OOB data\n");

13 Write(sockfd, "5", 1);

14 printf("wrote 1 byte of normal data\n");

15 exit(0);

16 }

Листинг 24.7. Принимающая программа, в которой вызывается функция sokatmark

//oob/tcprecv04.c

1 #include "unp.h"

2 int

3 main(int argc, char **argv)

4 {

5 int listenfd, connfd, n, on = 1;

6 char buff[100];

7 if (argc == 2)

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

9 else if (argc == 3)

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

11 else

12 err_quit("usage- tcprecv04 [ <host> ] <port#>");

13 Setsockopt(listenfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));

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

15 sleep(5);

16 for (;;) {

17 if (Sockatmark(connfd))

18 printf("at OOB mark\n");

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

20 printf("received EOF\n");

21 exit(0);

22 }

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

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

25 }

26 }

Включение параметра сокета SO_OOBINLINE

13
Мы хотим принимать внеполосные данные вместе с обычными данными, поэтому нам нужно включить параметр
SO_OOBINLINE
. Но если мы будем ждать, когда выполнится функция accept и установит этот параметр для присоединенного сокета, трехэтапное рукопожатие завершится и внеполосные данные могут уже прибыть. Поэтому нам нужно установить этот параметр еще для прослушиваемого сокета, помня о том, что все параметры прослушиваемого сокета наследуются присоединенным сокетом (см. раздел 7.4).

Вызов функции sleep после вызова функции accept

14-15
После того как выполнена функция
accept
, получатель переходит в спящее состояние, что позволяет получить все данные, посланные отправителем. Это позволяет нам продемонстрировать, что функция read останавливается на отметке внеполосных данных, даже если в приемном буфере сокета имеются дополнительные данные.

Считывание всех отправленных данных

16-25
В программе имеется цикл, в котором вызывается функция
read
и выводятся полученные данные. Но перед вызовом функции
read
функция
sockatmark
проверяет, находится ли указатель буфера на отметке внеполосных данных.

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

Идеальный мир для Лекаря 17

Сапфир Олег
17. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 17

Столичный доктор. Том III

Вязовский Алексей
3. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том III

Камень. Книга восьмая

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

Академия

Кондакова Анна
2. Клан Волка
Фантастика:
боевая фантастика
5.40
рейтинг книги
Академия

Князь Мещерский

Дроздов Анатолий Федорович
3. Зауряд-врач
Фантастика:
альтернативная история
8.35
рейтинг книги
Князь Мещерский

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

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

Всплеск в тишине

Распопов Дмитрий Викторович
5. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Всплеск в тишине

Камень. Книга 3

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

Мастер 2

Чащин Валерий
2. Мастер
Фантастика:
фэнтези
городское фэнтези
попаданцы
технофэнтези
4.50
рейтинг книги
Мастер 2

СД. Том 17

Клеванский Кирилл Сергеевич
17. Сердце дракона
Фантастика:
боевая фантастика
6.70
рейтинг книги
СД. Том 17

Варлорд

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

Проект ’Погружение’. Том 1

Бредвик Алекс
1. Проект ’Погружение’
Фантастика:
фэнтези
рпг
постапокалипсис
5.00
рейтинг книги
Проект ’Погружение’. Том 1

Отборная бабушка

Мягкова Нинель
Фантастика:
фэнтези
юмористическая фантастика
7.74
рейтинг книги
Отборная бабушка

Дорога к счастью

Меллер Юлия Викторовна
Любовные романы:
любовно-фантастические романы
6.11
рейтинг книги
Дорога к счастью