Когда срочные данные прибывают по назначению, получающее приложение прерывается (то есть в терминологии UNIX «получает сигнал»), после чего оно может считать данные из входного потока и найти среди них срочные. Конец срочных данных маркируется, так что приложение может распознать, где они заканчиваются. Начало срочных данных не маркируется. Приложение должно само догадаться.
Такая схема представляет собой грубый сигнальный механизм, оставляя все прочее приложению. Хотя теоретически использование срочных данных выглядит целесообразным, в первое время после своего появления эта схема не была хорошо реализована и поэтому быстро вышла из употребления. Сейчас использовать ее не рекомендуется из-за трудностей реализации, так что приложения вынуждены прибегать к своим собственным системам сигналов. Возможно, в последующих транспортных протоколах эта идея будет реализована лучше.
6.5.3. Протокол TCP
В данном разделе будет рассмотрен протокол TCP в общих чертах. В следующем разделе мы обсудим заголовок протокола, поле за полем.
Ключевым свойством TCP, определяющим всю структуру протокола, является то, что в TCP-соединении у каждого байта есть свой 32-разрядный порядковый номер. В первые годы существования Интернета базовая скорость передачи данных между маршрутизаторами по выделенным линиям составляла 56 Кбит/с. Хосту, постоянно выдающему данные с максимальной скоростью, потребовалось бы больше недели на то, чтобы порядковые номера совершили полный круг. При нынешних скоростях порядковые номера могут кончиться очень быстро, об этом еще будет сказано ниже. Отдельные 32-разрядные порядковые номера используются для указания позиции скользящего окна в одном направлении и подтверждений в обратном направлении, о чем также будет сказано ниже.
Отправляющая и принимающая TCP-подсистемы обмениваются данными в виде сегментов. Сегмент TCPсостоит из фиксированного 20-байтового заголовка (плюс необязательная часть), за которым могут следовать байты данных. Размер сегментов определяется программным обеспечением TCP. Оно может объединять в один сегмент данные, полученные в результате нескольких операций записи, или, наоборот, распределять результат одной записи между несколькими сегментами. Размер сегментов ограничен двумя пределами. Во-первых, каждый сегмент, включая TCP-заголовок, должен помещаться в 65 515-байтное поле полезной нагрузки IP-пакета. Во-вторых, в каждом канале есть максимальный размер передаваемого блока( MTU, Maximum Transfer Unit). На отправителе и получателе каждый сегмент должен помещаться в MTU, чтобы он мог передаваться и приниматься в отдельном пакете, не разделенном на фрагменты. На практике максимальный размер передаваемого блока составляет обычно 1500 байт (что соответствует размеру поля полезной нагрузки Ethernet), и таким образом определяется верхний предел размера сегмента.
Тем не менее, если IP-пакет, содержащий TCP-сегменты, проходит по пути со слишком низким MTU, его фрагментация возможна. Но в таком случае снижается производительность, а также возникают другие проблемы (Kent и Mogul, 1987). Вместо этого реализации TCP выполняют обнаружение MTU маршрута. При этом используется метод, описанный в RFC 1191, — о нем мы говорили в разделе 5.5.5. Этот метод вычисляет минимальное значение MTU по всем каналам пути, используя сообщения об ошибках ICMP. На основе этого значения TCP выбирает размер сегмента, позволяющий избежать фрагментации.
Основным протоколом, используемым TCP-подсистемами, является протокол скользящего окна с динамическим размером окна. При передаче сегмента отправитель включает таймер. Когда сегмент прибывает в пункт назначения, принимающая TCP-подсистема посылает обратно сегмент (с данными, если есть, что посылать, иначе — без данных) с номером подтверждения, равным порядковому номеру следующего ожидаемого сегмента, и новым размером окна. Если время ожидания подтверждения истекает, отправитель посылает сегмент еще раз.
Хотя этот протокол кажется простым, в нем имеется несколько деталей, которые следует рассмотреть подробнее. Сегменты могут приходить в неверном порядке. Так, например, возможна ситуация, в которой байты с 3072 по 4095 уже прибыли, но подтверждение для них не может быть выслано, так как байты с 2048 по 3071 еще не получены. К тому же сегменты могут задерживаться в сети так долго, что у отправителя истечет время ожидания, и он передаст их снова. Переданный повторно сегмент может включать в себя уже другие диапазоны фрагментов, поэтому потребуется очень аккуратное администрирование для определения номеров байтов, которые уже были приняты корректно. Тем не менее, поскольку каждый байт в потоке единственным образом определяется по своему сдвигу, эта задача оказывается реальной.
Читать дальше
Конец ознакомительного отрывка
Купить книгу