В реализациях, происходящих от Беркли [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
. Это
2.