UNIX: разработка сетевых приложений
Шрифт:
24.1. Введение
Ко многим транспортным уровням применима концепция внеполосных данных( out-of-band data), которые иногда называются срочными данными( expedited data). Суть этой концепции заключается в том, что если на одном конце соединения происходит какое-либо важное событие, то требуется быстро сообщить об этом собеседнику. В данном случае «быстро» означает, что сообщение должно быть послано прежде, чем будут посланы какие-либо обычные данные (называемые иногда данными из полосы пропускания), которые уже помещены в очередь для отправки, то есть внеполосные данные имеют более высокий приоритет, чем обычные данные. Для передачи внеполосных данных не создается новое соединение, а
К сожалению, когда мы переходим от общих концепций к реальной ситуации, почти в каждом транспортном протоколе имеется своя реализация внеполосных данных. В качестве крайнего примера можно привести UDP, где внеполосных данных нет вовсе. В этой главе мы уделим основное внимание модели внеполосных данных TCP. Мы приведем различные примеры обработки внеполосных данных в API сокетов и опишем, каким образом внеполосные данные используются приложениями Telnet, Rlogin и FTP. За пределами очерченного круга удаленных интерактивных приложений найти применение внеполосным данным довольно сложно.
24.2. Внеполосные данные протокола TCP
В протоколе TCP нет настоящих внеполосных данных. Вместо этого в TCP предусмотрен так называемый срочный режим [4] ( urgent mode), к рассмотрению которого мы сейчас и приступим. Предположим, процесс записал Nбайт данных в сокет протокола TCP, и эти данные образуют очередь в буфере отправки сокета и ожидают отправки собеседнику. Ситуацию иллюстрирует рис. 24.1. Байты данных пронумерованы от 1 до N.
4
Иногда переводится как «экстренный режим» или «режим срочности». — Прим. перев.
Рис. 24.1. Буфер отправки сокета, содержащий данные для отправки
Теперь процесс отправляет один байт внеполосных данных, содержащий символ ASCII
TCP помещает данные в следующую свободную позицию буфера отправки сокета и устанавливает указатель на срочные данные (или просто срочный указатель [5] — urgent pointer) для этого соединения на первую свободную позицию. Этот буфер показан на рис. 24.2, а байт, содержащий внеполосные данные, помечен буквами
5
Также (ошибочно) используется термин «указатель срочности». — Примеч. перев.
Рис. 24.2. Буфер отправки сокета, в который добавлен один байт внеполосных данных
Срочный указатель TCP указывает на байт данных, который следует за последним байтом внеполосных данных (то есть данных, снабженных флагом MSG_OOB). В книге [111] на с. 292-296 говорится, что это исторически сложившаяся особенность, которая теперь эмулируется во всех реализациях. Если посылающий и принимающий протоколы TCP одинаково интерпретируют срочный указатель TCP, беспокоиться не о чем.
Если состояние буфера таково, как показано на рис. 24.2, то в заголовке TCP следующего отправленного сегмента будет установлен флаг URG, а поле смещения срочных данных (или просто поле срочного смещения [6] ) будет указывать на байт, следующий за байтом с внеполосными данными. Но этот сегмент может содержать байт, помеченный как OOB, а может и не содержать его. Будет ли послан этот байт, зависит от количества предшествующих ему байтов в буфере отправки сокета, от размера сегмента, который TCP пересылает собеседнику, и от текущего размера окна, объявленного
собеседником.6
Также используется термин «срочное смещение». — Примеч. перев.
Выше мы использовали термины «срочный указатель» (urgent pointer) и «срочное смещение» (urgent offset). На уровне TCP эти термины имеют различные значения. Величина, представленная 16 битами в заголовке TCP, называется срочным смещением и должна быть прибавлена к полю последовательного номера в заголовке TCP для получения 32-разрядного последовательного номера последнего байта срочных данных (то есть срочного указателя). TCP использует срочное смещение, только если в заголовке установлен другой бит, называемый флагом URG. Программисту можно не заботиться об этом различии и работать только со срочным указателем TCP.
Важная характеристика срочного режима TCP заключается в следующем: заголовок TCP указывает на то, что отправитель вошел в срочный режим (то есть флаг URG установлен вместе со срочным смещением), но фактической отправки байта данных, на который указывает срочный указатель, не требуется. Действительно, если поток данных TCP остановлен функциями управления потоком (когда буфер приема сокета получателя заполнен и TCP получателя объявил нулевое окно для отправляющего TCP), то срочное уведомление отправляется без каких-либо данных [128, с. 1016–1017], как показано в листингах 24.8 и 24.9. Это одна из причин, по которой в приложениях используется срочный режим TCP (то есть внеполосные данные): срочное уведомление всегда отсылается собеседнику, даже если поток данных остановлен функциями управления потоком TCP.
Что произойдет, если мы отправим несколько байтов внеполосных данных, как в следующем примере?
В этом примере срочный указатель TCP указывает на байт, следующий за последним байтом, и таким образом, последний байт (
Посмотрим теперь, как выглядит процесс отправки внеполосных данных с точки зрения принимающей стороны.
1. Когда TCP получает сегмент, в котором установлен флаг URG, срочный указатель проверяется для выяснения того, указывает ли он на новыевнеполосные данные. Иначе говоря, проверяется, впервые ли этот конкретный байт передается в срочном режиме TCP. Дело в том, что часто отправляющий TCP посылает несколько сегментов (обычно в течение короткого промежутка времени), содержащих флаг URG, в которых срочный указатель указывает на один и тот же байт данных. Только первый из этих сегментов фактически уведомляет принимающий процесс о прибытии новых внеполосных данных.
2. Принимающий процесс извещается о том, что прибыли новые внеполосные данные. Сначала владельцу сокета посылается сигнал
Эти два уведомления действуют в том случае, когда прибывает новый срочный указатель, вне зависимости от того, принят ли байт, на который он указывает.
В потоке данных может быть только одна отметка OOB (один срочный указатель). Если новый срочный байт отправляется до того, как будет принят старый, последний просто сбрасывается и перестает быть срочным.
3. Когда байт данных, на который указывает срочный указатель, фактически прибывает на принимающий TCP, этот байт может быть помещен отдельно или оставлен вместе с другими данными. По умолчанию параметр сокета