Для решения этой проблемы необходимо, чтобы получатель освобождал место в своем приемном буфере, считывая поступившие обычные данные. В результате TCP объявит для отправителя окно ненулевого размера, что в конечном счете позволит отправителю передать байт, содержащий внеполосные данные.
ПРИМЕЧАНИЕ
В реализациях, происходящих от Беркли [128, с. 1016-1017], можно отметить две близких проблемы. Во-первых, даже если приемный буфер сокета заполнен, ядро всегда принимает от процесса внеполосные данные для отправки собеседнику. Во-вторых, когда отправитель посылает байт с внеполосными данными, немедленно посылается сегмент TCP, содержащий срочное уведомление. Все обычные проверки вывода TCP (алгоритм Нагла, предотвращение синдрома «глупого окна») при этом блокируются.
Пример: единственность отметки внеполосных данных в TCP
Нашим очередным примером мы иллюстрируем тот факт, что для данного соединения TCP существует всего одна отметка внеполосных данных, и если новые внеполосные данные прибудут прежде, чем принимающий процесс начнет считывать пришедшие ранее внеполосные данные, то предыдущая отметка будет утеряна.
В листинге 24.10 показана посылающая программа, аналогичная программе, приведенной в листинге 24.6. Отличие заключается в том, что сейчас мы добавили еще одну функцию send
для отправки внеполосных данных и еще одну функцию write
для записи обычных данных.
Листинг 24.10. Отправка двух байтов внеполосных данных друг за другом
//oob/tcpsend06.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 ");
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 Send(sockfd,. "6", 1, MSG_OOB);
16 printf("wrote 1 byte of OOB data\n");
17 Write(sockfd, "7", 1);
18 printf("wrote 1 byte of normal data\n");
19 exit(0);
20 }
В данном случае отправка данных происходит без пауз, что позволяет быстро переслать данные собеседнику.
Принимающая программа идентична программе, приведенной в листинге 24.7, где вызывается функция sleep
, которая после установления соединения переводит получателя в спящее состояние на 5 с, чтобы позволить данным прибыть на принимающий TCP. Ниже приводится результат выполнения этой программы:
freebsd4 % tcprecv06 5555
read 5 bytes: 12345
at OOB mark
read 2 bytes: 67
received EOF
Прибытие второго байта внеполосных данных ( 6
) изменяет отметку, которая ассоциировалась с первым прибывшим байтом внеполосных данных ( 4
). Как мы сказали, для конкретного соединения TCP допускается только одна отметка внеполосных данных.
24.4. Резюме по теме внеполосных данных TCP
Все приведенные до сих пор примеры, иллюстрирующие использование внеполосных данных, были весьма тривиальны. К сожалению, когда мы начинаем учитывать возможные проблемы, связанные с согласованием во времени при пересылке внеполосных данных, ситуация заметно усложняется. В первую очередь, нужно осознать, что концепция внеполосных данных подразумевает передачу получателю трех различных фрагментов информации:
1. Сам факт того, что отправитель вошел в срочный режим. Принимающий процесс получает уведомление об этом либо с помощью сигнала SIGURG
, либо с помощью функции select
. Это уведомление передается сразу же после того, как отправитель посылает байт внеполосных данных, поскольку, как показано в листинге 24.9, TCP посылает уведомление, даже если поток каких-либо данных от сервера к клиенту остановлен функциями управления потоком. В результате получения такого уведомления получатель может входить в определенный специальный режим обработки последующих данных.
2. Позиция байта, содержащего внеполосные данные, то есть расположение этого байта по отношению к остальным данным, посланным отправителем, иначе говоря, отметка внеполосных данных.
3. Фактическое значение внеполосного байта. Поскольку TCP является потоковым протоколом, который не интерпретирует данные, посланные приложением, это может быть любое 8-разрядное значение.
Говоря о срочном режиме TCP, мы можем рассматривать флаг URG как уведомление, а срочный указатель как внеполосную отметку.
Проблемы, связанные с концепцией внеполосных данных, сформулированы в следующих пунктах:
Читать дальше
Конец ознакомительного отрывка
Купить книгу