1. Транспортный уровень

 

6.1.Сервис

6.1.1.Сервис для верхних уровней

6.1.2.Качество сервиса

6.1.3.Примитивы транспортного уровня

6.2.Элементы транспортного протокола

6.2.1.Адресация

6.2.2.Установление соединения

6.2.3.Освобождение соединения

6.2.4.Управление потоком и буферизация

6.2.5.Мультиплексирование

6.2.6.Восстановление разрывов

6.3.Простой транспортный протокол

6.3.1.Пример сервисных примитивов

6.3.2.Пример транспортного протокола

6.3.3.Пример конечного автомата

6.4.Транспортные протоколы в Internet: TCP и UDP

6.4.1.Сервис TCP

6.4.2.Протокол TCP

6.4.3.Заголовок сегмента в TCP

6.4.4.Управление соединениями в TCP

6.4.5.Стратегия передачи в TCP

6.4.6.Управление заторами в TCP

6.4.7.Управление таймером в TCP

6.4.8.Протокол UDP

6.4.9.Беспрводный TCP и UDP

6.5.ATM AAL протокол

6.5.1.Структура уровня адаптации в АТМ

6.5.2.AAL1

6.5.3.AAL2

6.5.4.AAL 3/4

6.5.5.AAL 5

6.5.6.Сравнение AAL протоколов

6.6.Производительность

6.6.1.Проблемы производительности в сетях

6.6.2.Измерение производительности в сети

6.6.3.Правила, улучшающие производительность

6.6.4.Быстрая обработка TPDU

6.7.Протоколы для гигабитных сетей

 

 

 

Транспортный протокол - это центральный протокол во всей иерархии протоколов. Именно он обеспечивает надежную передачу данных от одного абонента в сети другому. Здесь мы рассмотрим достаточно подробно организацию, сервис, протоколы и производительность.

 

6.1.Сервис

Здесь мы рассмотрим какие виды сервиса транспортный уровень предоставляет прикладному, как характеризуется качество предоставляемого сервиса, как обеспечивается доступ из прикладного уровня к транспортному, как выглядит интерфейс.

 

6.1.1.Сервис для верхних уровней

Основная цель транспортного уровня - обеспечить эффективный, надежный и дешевый сервис для пользователей на прикладном уровне. Достижение этой цели обеспечивает сервис, предоставляемый сетевым уровнем. То, что выполняет работу транспортного уровня, называется транспортным агентом. Транспортный агент может располагаться в ядре операционной системы, в отдельном процессе пользователя, в библиотеке сетевого приложения, на карте сетевого интерфейса. В некоторых случаях оператор сети может предоставлять надежный транспортный сервис, при котором транспортный агент располагается на специальной интерфейсной машине на границе подсети, к которой подключены абонентские машины. На рис.6-1 показаны взаимные расположения сетевого, транспортного и прикладного уровней.

Подобно тому, как сетевой уровень имеет два вида сервиса: ориентированный на соединения и не ориентированный, транспортный так же имеет сервис, ориентированный на соединения и без соединений. Транспортный сервис, ориентированный на соединение, очень схож с сетевым сервисом, ориентированным на соединение. Адресация и управление потоком также схожи на обоих уровнях.

Тогда возникает вопрос: Если сервис сетевого уровня столь схож с сервисом транспортного, то зачем два разных уровня? Причина этого состоит в том, что сетевой уровень - это часть подсети передачи данных, которой управляет оператор подсети. Что будет, если сетевой уровень предоставляет ненадежный сервис, ориентированный на соединения? Предположим, что он часто теряет пакеты? Что делать, если маршрутизатор время от времени отказывает?

У пользователя подсетью нет средств для решения такой проблемы, если она возникла. Для того, чтобы ему дать такую возможность, надо поверх сетевого пустить еще один уровень, который позволит исправлять качество сетевого уровня. Если транспортному уровню придет сообщение, что соединение на сетевом уровне неожиданно было разорвано, то он может установить новое сетевое соединение, с помощью которого выяснить, что произошло, какие данные были переданы, а какие нет и т.п.

Существо транспортного уровня в том, чтобы сделать сервис транспортного уровня более надежным, чем сетевого. Другое важное соображение в том, что прикладная программа, опираясь на транспортный сервис, становится независимой от сети и может работать в сети с любым сервисом. И, на конец, с транспортным сервисом работает прикладная программа, а с сетевым √ транспортный уровень. Поэтому, интерфейс с транспортным уровнем должен быть дружественным, удобным и эффективным.

В силу приведенных доводов первые четыре уровня называют поставщиками транспортного сервиса, а все что выше четвертого - пользователями транспортного сервиса.

 

6.1.2. Качество сервиса

Мы уже встречались с понятием качества сервиса при рассмотрении сетевого уровня, где рассматривали набор параметров, с помощью которых можно охарактеризовать это понятие. Транспортный уровень позволяет пользователю определить желаемые, допустимые и минимальные значения для различных параметров в момент установки соединения. Далее сам транспортный уровень будет решать, сможет ли он с помощью сетевого сервиса удовлетворить запросы пользователя и до какой степени. На рис.6-2 перечислены основные параметры сервиса. Заметим, что лишь немногие сети поддерживают все эти параметры.

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

Процедура согласования параметров качества сервиса называется согласованием возможностей.

 

6.1.3. Примитивы транспортного уровня

Примитивы транспортного уровня позволяют пользователю получить доступ к транспортному сервису. Транспортный сервис аналогичен сетевому. Между ними существует одна большая разница - сетевой сервис по природе своей не надежен. Задача транспортного сервиса, как раз, обеспечить надежную доставку сообщений. Два процесса, соединенные между собой, ничего не должны знать о том, как физически они соединены. Один помещает данные на вход другого, другой получает их. Задача транспортного уровня спрятать от них все детали передачи, исправления ошибок и т.п.

Транспортный сервис может быть как ориентированный на соединения, так и нет. Дейтаграммный транспортный сервис возможен, но это редкость, поэтому мы будем рассматривать транспортный сервис, ориентированный на соединения.

Другое важное отличие между сетевым и транспортным сервисами - кто их использует. Сетевой - использует транспортный, а вот транспортный - использует пользователь, прикладные программы. Поэтому он должен быть ориентирован на пользователя: удобен, прост в использовании.

Общее представление о примитивах транспортного сервиса дает рис.6-3. Этот пример содержит основные виды примитивов для установления соединения, передачи данных и разрыва соединения, что вполне достаточно для многих приложений.

Использование этих примитивов может быть продемонстрировано следующим образом. Сервер приложения выполняет примитив LISTEN, в результате чего он блокируется до поступления запросов от клиентов. Клиент для установления соединения выполняет примитив CONNECT. Транспортный агент на стороне клиента блокирует клиента и посылает пакет с запросом на установление соединения серверу.

Напомним, что транспортные агенты обмениваются пакетами, которые имеют специальное название - Transport Protocol Data Unit (TPDU). Взаимосвязь между кадрами, пакетами и TPDU показана на рис.6-4.

По примитиву CONNECT транспортный агент на стороне клиента шлет TPDU CONNECTION REQUEST. Транспортный агент сервера, видя, что сервер заблокирован по LISTEN, разблокирует сервер и посылает CONNECTION ACCEPTED TPDU. После этого транспортное соединение считается установленным. После этого наступает обмен данными с помощью примитивов SENT и RECEIVE.

По окончании обмена соединение должно быть разорвано. Есть два варианта разрыва соединения: симметричный и асимметричный. Асимметричные предполагает, что для разрыва соединения одна из сторон посылает DISCONNECT TPDU. Получив этот TPDU, другая сторона считает соединение разорванным.

При симметричном разрыве каждое направление закрывается отдельно. Когда одна сторона посылает DISCONNECT TPDU, это значит, что с ее сторона больше данных не будет. На рис.6-5 показана диаграмма состояний при установлении и разрыве соединения.

На рис.6-6 показан другой набор примитивов - сокеты Беркли. Здесь два основных отличия от того, что мы только что рассмотрели. Первое - создается точка подключения соединения (SOCET), которой присваивается адрес (BIND). Второе - LISTEN не блокирующий примитив. Он создает очередь, если несколько клиентов будут обращаться за соединением в одно и то же время.

 

6.2.Элементы транспортного протокола

Транспортный сервис реализует транспортный протокол, который используют взаимодействующие транспортные агенты. Транспортный протокол в чем-то схож с канальным. Однако между ними много различий:

  1. они работают в разных средах ( см.рис.6-7);
  2. процессы на канальном уровне взаимодействуют через провод, поэтому процедура установления соединения много проще;
  3. среда, в которой работает транспортный протокол, обладает памятью, которая может теряться;
  4. количество соединений, которое может возникать на транспортном уровне, много больше, чем на канальном, что создает дополнительные проблемы для буферизации и управления потоком.

Транспортный протокол должен решать следующие проблемы:

  1. Адресация: как адресовать прикладной процесс, с которым надо установить соединение?
  2. Как корректно установить соединение? Ведь пакеты могут теряться. Как отличить пакеты нового соединения от повторных пакетов, оставшихся от старого?
  3. Как корректно разрывать соединение?

 

6.2.1.Адресация

Проблема адресации состоит в том, как указать с каким удаленным прикладным процессом надо установить соединение? Обычно для этого используется транспортный адрес, по которому прокладной процесс может слушать запросы на соединение. Мы будем использовать термин TSAP - Transport Service Access Point. Аналогичное понятие существует и на сетевом уровне - IP адрес - SAP для сетевого уровня.

На рис.6-8 показано взаимосвязь ТSAP и NSAP. Он же иллюстрирует сценарий использования ТSAP для установления соединения между двумя удаленными процессами. В этой иллюстрации в целом все правильно. Не ясно лишь как прикладной процесс на машине 1 узнает, что интересующий его сервер подключен к ТSAP 122 на машине 2? Одно из возможных решений - данный сервер всегда подключен к ТSAP 122 и все об этом знают.

Это решение хорошо работает для часто используемого сервиса с длительным периодом активности, но как быть прикладным процессам пользователя, который может возникать спорадически на короткое время? Одно из решение, используемых в Unix, показано на рис.6-9. Оно называется протоколом установления начального соединения. На каждой машине есть специальный сервер процессов, который как бы представляет все процессы исполняемые на этой машине. Этот сервер слушает несколько ТSAP куда могут поступить запросы на ТСР соединение. Если нет свободного сервера, способного выполнить запрос, то соединение устанавливается с сервером процесса, который переключит соединение на нужный сервер, как только он освободится.

Однако, есть случаи когда этот подход с сервером процессов не работает. Не всегда можно запускать сервер сервиса по требованию пользователя. Например, файл сервер. Он должен существовать всегда. Решение в этом случае - сервер имен. Пользователь устанавливает соединение с сервером имен, для которого ТSAP известен, и передает ему имя сервиса. В ответ сервер имен шлет надлежащий ТSAP. Клиент разрывает соединение с сервером имен и устанавливает его по полученному адресу.

Пусть пользователь узнал ТSAP, но как он узнает на какой машине этот ТSAP расположен, какой сетевой адрес надо использовать? Ответ заключается в структуре ТSAP адреса, где заключается вся необходимая информация. Этот адрес имеет иерархическую структуру.

 

6.2.2.Установление соединения

Проблема установления транспортного соединения сложна потому, что пакеты могут теряться, храниться и дублироваться на сетевом уровне.

Трудный пример - установление соединения с банком для перевода денег с одного счета на другой. Из-за перегрузки в сети или по какой-либо другой причине может произойти большая задержка. Тогда по time_out активная сторона вышлет еще один запрос. Пакеты-дубли могут вызвать повторное соединение и вторичный перевод денег. Проблема здесь в задержках и появлении пакетов дубликатов. Как быть?

Одно из возможных решений - временное ТSAP. Когда оно использовано, использованный адрес более не возникает. При этом решении не работает модель с сервером процессов на рис.6-9.

Другое решение - каждому транспортному соединению сопоставлять уникальный номер. Когда соединение разрывается, этот номер заносится в специальный список. К сожалению, этот список может расти бесконечно. Кроме этого, в случае сбоя машины он может быть потерян и тогда ...

Другой подход - ограничить время жизни пакетов. Это можно достичь тремя путями:

  1. Ограничением конструкции подсети;
  2. Установкой счетчиков скачков в каждом пакете;
  3. Установлением временной метки на каждом пакете.

Заметим, что последний метод требует синхронизации маршрутизаторов в сети.

На практике нам надо обеспечить, чтобы умерли не только сами пакеты, но и уведомления о них. Это значит, что надо ввести величину Т такую, что по ее истечении в сети не осталось ни самого пакета ни уведомления о нем.

При ограничении времени жизни пакета можно построить безопасный способ установления соединения. Этот метод был предложен Томлинсоном. Его идея состоит в том, что все машины в сети оснащены таймерами. Каждый таймер двоичный счетчик достаточно большой разрядности, равной или превосходящей разрядность последовательных чисел, используемых для нумерации пакетов. При установлении соединения несколько младших разрядов берут в качестве начального номера. Главное чтобы последовательности номеров пакетов одного соединения не приводили к переполнению счетчика и его обнулению. Эти номера можно также использовать для управления потоком, в протоколе скользящего окна.

Проблема возникает, когда машина восстанавливается после сбоя. Транспортный агент не знает в этот момент, какое число можно использовать для очередного номера Для того, чтобы избежать повторного использования порядкового номера, который уже был сгенерирован перед сбоем машины, вводится специальная величина по времени, которая образует запрещенную область последовательных номеров (см.рис.6-10).

Пусть Т максимальное время жизни пакета в сети. Предположим для простоты, что в момент x начальный номер будет x, и что максимальное время жизни пакета равно 60 сек. Пусть в t=30 сек , был послан пакет с номером 80. Пусть в момент t=60 машина была восстановлена после падения и в момент t=70 появился пакет с номером 80. Однако, старый пакет с номером 80 все еще существует. Поэтому вводят для каждого момента времени область запрещенных номеров. Машина, восстановленная после сбоя, не может выбирать номера из этой запретной зоны.

Проблема номеров может возникать по двум причинам. Либо потому, что машина генерирует слишком быстро пакеты и соединения, либо потому, что делает это слишком медленно. Чем больше разрядность счетчика последовательных номеров, тем дальше отодвигается момент попадания в запретную область.

Другая нетривиальная проблема - надежное установление соединения: пакеты ведь могут пропадать. Для ее решения Томлинсон предложил процедуру троекратного рукопожатия (рис.6-11).

Эта процедура предполагает, что машина 1 шлет запрос на установление соединения под номером x. Машина 2 шлет подтверждение на запрос x, но со своим номером у. Машина 1 подтверждает получение подтверждения с номером у. На рис.6-11b,c показано, что будет, если поступит западавший запрос на соединение, и, запрос и подтверждение на него.

 

6.2.3.Разрыв соединения

Разрыв соединения, как уже было сказано, может быть асимметричным или симметричным. Асимметричный разрыв может привести к потере данных (см. рис.6-12). Симметричный разрыв - каждая сторона проводит самостоятельно, когда она передала весь имеющийся объем данных. Однако, определить этот факт не всегда просто. Здесь есть одна проблема, которая называется проблемой двух армий (см. рис.6-13).

Внимательно изучив проблему разрыва соединения, мы придем к выводу, что ни одна армия не начнет атаки до тех пор, пока не получит подтверждения на подтверждение и так до бесконечности. На самом деле, можно доказать, что нет протокола, который безопасно разрешает эту ситуацию. На рис.6-14 показаны четыре сценария разрыва соединения. Обычно, эту проблему решают, фиксируя число попыток разрыва.

 

6.2.4.Управление потоком и буферизация

Теперь, рассмотрев, как устанавливают соединение, рассмотрим, как им управляют. Прежде всего, рассмотрим управление потоком. Проблема управления потоком на транспортном уровне в чем-то аналогична проблеме управления потоком на канальном уровне. Различия в том, что у маршрутизатора число линий не велико, в то время как на транспортном уровне соединений может быть очень много.

Канальный протокол сохранял пакеты, как на стороне отправителя, так и на стороне получателя. Если у нас есть 64 соединения и время жизни пакета требует 4 разрядов, то нам потребуется 1024 буфера. Число буферов можно сократить, если есть информация о надежности сетевого уровня или о наличии буфера у получателя. На транспортном уровне отправитель сохраняет все пакеты на случай, если какой-то из них придется посылать вторично. Получатель может иметь лишь пул буферов для всех соединений и, если пришел пакет и ему нет буфера в пуле, то он сбрасывается, в противном случае сохраняется и подтверждается.

Если сетевой уровень не надежный, то на транспортном уровне отправитель вынужден сохранять все отправленные и не подтвержденные пакеты. При надежном сетевом сервисе, наоборот отправителю нет нужды сохранять отправленные пакеты.

Однако, и в первом и во втором случае возникает проблема размера буфера. При фиксированной длине буфера, естественно организовывать пул буферов одного и того же размера. Однако, при переменной длине пакетов проблема становится много сложнее. Если размер буфера устанавливать по максимальной длине пакета, то мы столкнемся с проблемой фрагментации. Если по минимальной, то один пакет придется пересылать как несколько с дополнительными накладными расходами. Можно установить схему динамического согласования размера буфера при установлении соединения.

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

Другую проблему представляет согласование доступного числа буферов и пропускная способность сетевого уровня. В настоящее время память дешевеет, поэтому буферизация скоро не будет представлять проблему. Другое дело проблема пропускной способности сетевого уровня. Эту проблему лучше всего решать динамически с помощью управляющих сообщений. Механизм управления потоком должен, прежде всего, учитывать пропускную способность подсети, а уже потом возможности буферизации. Располагаться этот механизм должен на стороне отправителя, чтобы предотвращать накопление большого числа не подтвержденных сообщений.

 

6.2.5.Мультиплексирование

Мультиплексирование нескольких потоков на одном уровне на соединение, виртуальный канал, физическую линию на других возникает постоянно. Эта проблема возникает и на транспортном уровне.

Например, если пользователь за терминалом установил транспортное соединение отошел попить кофе, то транспортное соединение продолжает поддерживаться, резервируются под него буферное пространство, пространство в таблице маршрутизации и т.д. В целях удешевление стоимости транспортных соединений можно отобразить несколько транспортных соединений на одно сетевое. Такое отображение называется нисходящим мультиплексированием. Оно показано схематично на рис.6-17а.

В некоторых случаях наоборот, в целях увеличения пропускной способности по отдельным транспортным соединениям, можно отобразить транспортное соединение на несколько сетевых и по каждому сетевому иметь свое скользящее окно. Тогда быстро исчерпав возможности одного оконного буфера, можно переключиться на другое сетевое соединение и продолжить передачу по нему. Такое мультиплексирование называется восходящим. Рис.6-17в.

 

6.2.6.Восстановление после сбоев

Восстановление после сбоев будем рассматривать в предположении, что транспортный агент целиком располагается на машине. Восстановление сетевого уровня достаточно просто. Если сетевой уровень предоставляет дейтаграммный сервис, то транспортный уровень знает как исправлять подобные ситуации. При сервисе ориентированном на соединении, в случае потери соединения, транспортный уровень восстановить потерянное соединение и постарается в диалоге с транспортным агентом на другой стороне выяснить, что успели передать, а что нет.

Проблема становится много труднее когда надо восстанавливать работоспособность машины, включая и транспортный уровень. Рассмотрим случай, когда транспортный сервер взаимодействует с клиентами. Предположим, сервер упал и старается восстановить функционирование. Прежде всего, ему надо узнать у клиента, какое TPDU было последним не подтвержденным у него и попросить его перепослать. В свою очередь клиент может находиться в одном из двух состояний: S1 - есть не подтвержденное TPDU, либо S0 - все TPDU подтверждены.

Казалось бы все просто. Однако, рассмотрим проблему внимательнее. Сервер, получив TPDU, либо сначала шлет подтверждение, а затем записывает полученное TPDU в буфер приложения, либо сначала записывает, а потом шлет подтверждение. Если сервер упал, послав подтверждение, но до того, как он осуществил запись, то клиент будет находится после восстановления сервера в состоянии S0, хотя подтвержденное TPDU потеряно. Пусть наоборот сервер сначала записал TPDU, а потом упал. Тогда сервер после сбоя найдет клиента в состоянии S1 и решит, что надо перепослать не подтвержденное TPDU. В результате получим повторное TPDU.

Можно показать формально, что эта проблема только средствами транспортного уровня не решается. Надо, записав TPDU, информировать об этом приложение и только после этого слать подтверждение. При восстановлении надо опрашивать не только клиента на транспортном уровне, но и приложение.

 

6.3.Пример простого транспортного протокола

 

6.4.Транспортные протоколы в Internet: TCP и UDP

В Internet есть два основных транспортных протокола: TCP - ориентированный на соединение и UDP - не ориентированный на соединение. Поскольку UDP - это практически IP с добавлением небольшого заголовка, то основное внимание будет уделено TCP.

TCP (Transmission Control Protocol) - специально созданный протокол для надежной передачи потока байтов по соединению точка-точка через не надежную сеть. ТСР был сознательно разработан так, чтобы он мог адаптироваться к условиям и особенностям разных сетей, устойчиво и эффективно функционировать в условиях internet (нескольких сетей). На каждой машине, поддерживающей ТСР, есть ТСР агент либо в виде части ядра ОС, либо как часть процесса пользователя, который управляет ТСР потоками и доступом к IP.

ТСР получает поток данных от прикладного процесса, дробит их на части не более 64К ( на практике не более 1500) и отправляет их как отдельные IP дейтаграммы.

Поскольку IP уровень не гарантирует доставку каждой дейтаграммы, то в задачу ТСР входит определение потери и организация повторной передачи. Дейтаграммы могут поступать к получателю в неправильном порядке и опять-таки задача ТСР восстановить этот порядок.

 

6.4.1.Модель сервиса TCP

Доступ к ТСР сервису происходит через сокет. Сокет состоит из IP адреса хоста и 16 разрядного локального номера на хосте, называемого порт. Сокеты создаются как отправителем, так и получателем. Порт - это TSAP для ТСР. Каждое соединение идентифицируется парой сокетов, между которыми оно установлено. Один и тот же сокет может быть использован для разных соединений. Никаких дополнительных виртуальных соединений не создается.

Порты с номерами до 256 зарезервированы для стандартного сервиса. Например, если надо обеспечить FTP передачу файла, то надо соединяться на 21 порт, где находится FTP демон. Для TELNET - 23 порт. Полный список таких портов можно найти в RFC 1700.

Все ТСР соединения - дуплексные, т.е. передача идет независимо в оба направления. ТСР соединение поддерживает только соединение точка-точка. Нет ТСР соединений от одного ко многим.

ТСР обеспечивает поток байтов, а не поток сообщений. Напомним, это значит, что границы сообщений не поддерживаются автоматически в потоке.

Когда приложение передало данные ТСР, то они могут быть отправлены сразу, а могут быть за буферизованы - это решает ТСР агент. Однако, в ряде случаев надо, чтобы они были отправлены сразу, например, если набрана команда для удаленной машины. Для этого в заголовке ТСР пакета есть флаг PUSH. Если он установлен, это говорит о том, что данные должны быть переданы немедленно.

Наконец последняя возможность ТСР сервиса, которую здесь стоит упомянуть - срочные данные. Если для данных установлен флаг URGENT, то все данные после этого по данному соединению передаются сразу и не буферизуются. Когда срочные данные поступают к месту назначения, то получателя прерывают и передают эти данные.

 

6.4.2.Протокол TCP

Каждый байт в ТСР соединении имеет 32 разрядный номер. В сети на 10Мб/сек потребуется не менее часа, чтобы исчерпать все номера. Эти номера используются как для уведомления, так и в механизме управления окнами.

ТСР агенты обмениваются сегментами данных. Каждый сегмент имеет заголовок от 20 байтов и более (по выбору) и тело произвольной длины. Один сегмент может включать байты от разных отправителей, а может включать часть данных одного. ТСР агент решает какой длины может быть тело. Два фактора ограничивают длину сегмента. Первый - длина сегмента не должна превышать максимальную длину IP пакета - 65К байт. Второй - каждая сеть имеет максимальную единицу передачи MTU и каждый сегмент должен помещаться в MTU. В противном случае маршрутизаторам придется применять фрагментацию. При этом возрастают накладные расходы на передачу в сети, так как каждый фрагмент оформляется как самостоятельный пакет (20 байт заголовок).

Основным протоколом, используемым ТСР агентом, является протокол скользящего окна. Это значит, что каждый посланный сегмент должен быть подтвержден. Одновременно с отправлением сегмента взводится таймер. Подтверждение придет либо с очередными данными в обратном направлении, если они есть, либо без данных, но с подтверждением. Подтверждение будет иметь порядковый номер очередного ожидаемого получателем сегмента. Если таймер исчерпается прежде, чем придет подтверждение, то сегмент посылается повторно.

Несмотря на кажущуюся простоту, ТСР протокол достаточно сложен и должен решать следующие основные проблемы:

 

6.4.3.Заголовок сегмента в TCP

Заголовок ТСР сегмента показан на рис.6-24. Его многочисленные флаги мы будем рассматривать по ходу изложения. Максимальная длина раздела данные - 65 495 байтов. Source и Destination ports указывают сокеты на стороне отправителя и получателя. Sequence number и Acknowledgement number содержат порядковый номер начального байта. Причем последнее поле содержит номер первого ожидаемого, а не подтверждение последнего полученного байта.

6 битное поле флагов. Urgent бит используется вместе с полем Urgent pointer. Последнее поле указывает на начало области срочных данных.

ACK - 1 если поле Acknowledgement number используется. В противном случае оно - 0 .

PSH - если это поле 1, то отправитель просит транспортного агента на стороне получателя, сразу передать эти данные приложению и не буферизовать их.

RST - этот флаг используют, чтобы переустановить соединение, которое по какой-либо причине стало не корректным. Получив пакет с таким флагом, означает наличие проблемы, с которой надо разбираться.

SYN - 1 запрос на соединение. Флаг ACK указывает на наличие или отсутствие подтверждения. SYN =1 ACK =0 - запрос на соединение, SYN =1 ACK =1 - подтверждение на соединение.

FIN - запрос на разрыв соединение. У отправителя нет больше данных.

Поле Window size используется алгоритмом управления окном.

Options используется для установления возможностей, не предусмотренных стандартным заголовком. Например, здесь часто указывается максимальный размер поля данных, допустимый по данному соединению.

 

6.4.4.Управление соединениями в TCP

Установление ТСР соединения происходит по протоколу трехкратного рукопожатия. Флаги SYN и ASK в заголовке сегмента используются для обозначения CONNECTION REQUEST и CONNECTION ACCEPED. Флаг RST используется для обозначения REJECT.

На рис.6-26 показаны ситуации при установлении соединения. Когда пришел запрос на соединение по определенному порту, транспортный агент проверяет, есть ли процесс, который выполнил примитив LISTEN на этом порту. Если есть такой процесс, то ему передается управление. Если такого процесса нет, то в ответ идет отказ от установления соединения.

Случай b показывает ситуацию, когда два хоста одновременно пытаются установить соединение между двумя одинаковыми сокетами. Поскольку каждое соединение идентифицируется парой сокетов, то будет установлено только одно из соединений.

Таймер, для последовательных номеров сегментов, тактируется с частотой 4 mсек, а максимальное время жизни пакета - 120 сек. Напомним, что начальный номер сегментов никогда не равен нулю, по соображениям приведенным ранее. Для генерации последовательных номеров сегментов используют механизм логических часов.

ТСР соединение как уже говорилось дуплексное, т.е. в каждом направлении данные передают независимо и соединение разрывают независимо по каждому направлению. Поэтому лучше всего представлять его как два симплексных соединения. Если в очередном сегменте флаг FIN = 1, то в этом направлении данных больше не будет. При получении подтверждения для этого сегмента соединение в этом направлении считается разорванным. В другом направлении передача может продолжаться сколь угодно долго. Если подтверждения на первый FIN нет в течении двух интервалов жизни пакетов, то по time-out соединение считается разорванным. Противоположная сторона также по истечении этого периода времени знает, что никто не ждет ответа от нее. На рис.6-27 и 6.28 представлена процедура установления и разрыва соединения в виде диаграммы конечного автомата.

 

6.4.5.Стратегия передачи в TCP

Управление окнами в ТСР не связано прямо с поступлением подтверждений, как в управлении потоком на канальном уровне. Предположим, что у получателя есть буфера в 4096 байт, как показано на рис.6-29. Если отправитель послал сегмент в 2048 байт, то получатель, получив и подтвердив этот сегмент, будет показывать окно в 2048 байтов, до тех пор пока приложение не возьмет часть данных из полученного сегмента в 2048 байтов. Отправитель посылает следующие 2048 байт. Теперь размер окна равен 0 байт.

Когда поле WIN=0 отправитель может послать сегмент в двух случаях. Первый - если это URGENT данные. Например, чтобы убить процесс на удаленной машине. Второй, если это одно байтовый сегмент, чтобы заставить получателя показать текущее состояние буфера. Это очень важно так, как позволяет обойти тупик.

Заметим, что ТСР не требует от агента-отправителя сразу передавать сегмент, как только данные поступили от приложения. Эту свободу ТСР использует, чтобы повысить свою производительность. Пример, удаленный редактор через TELNET. Поэтому, часто при реализации ТСР вводят специальную задержку на посылку подтверждения и состояния окна, чтобы дать отправителю накопить буфер для отправки. Другую стратегию предложил Nagle - если работа идет с приложением, которое генерирует однобайтные сообщения, то надо первый байт послать, а все остальные буферизовать до тех пор, пока не придет подтверждение на посланный байт. Все буферизованные байты послать одним сегментом, после чего буферизовать все байты, пока не придет подтверждение на посланный сегмент.

Алгоритм Нагла работает хорошо. Однако есть приложения, где его следует отключить - X-Windows. Здесь перемещения мыши по экрану надо пересылать сразу без буферизации.

Другая проблема, которая может существенно понизить производительность ТСР - синдром дурацкого окна. Он возникает, когда приложение на стороне отправителя передает ТСР агенту данные большими блоками, а приложение на стороне получателя читает данные по байтно! В этой ситуации может произойти следующее. Буфер на стороне получателя полон и отправитель знает об этом. Приложение получатель считывает один байт из буфера. ТСР агент получателя радостно шлет сообщение о доступном буфере в один байт. Отправитель обязан послать один байт. После чего буфер получателя опять полон и т.д. Кларк предложил запретить сообщать получателю в таких случаях об освободившемся месте на один байт. Получателя принуждаю ждать либо пока не освободиться размер, равный максимальной длине сегмента, объявленной при установлении соединения, либо не освободиться половина буфера. Отправитель также должен стараться избегать крохотных сегментов, а слать большие.

У ТСР агента получателя также есть средства улучшить производительность соединения. Например, запретить приложению использовать примитив READ до тех пор, пока у агента есть данные в буфере. Конечно, такое решение увеличит время отклика, но для не интерактивных приложений это не страшно.

Другая проблема для получателя, понижающая производительность соединения, - нарушение порядка поступления сегментов. Например, если поступили 0,1,2,4,5,6,7 сегменты, получатель может подтвердить 0-2 сегменты, забуферизовать 4-7 сегменты. Тогда отправитель по time-out перешлет сегмент 3, после чего получатель подтвердит 4-7 сегменты.

 

6.4.6.Управление перегрузками в TCP

Здесь мы рассмотрим, как ТСР борется с перегрузками. В основе лежит принцип сохранения количества пакетов. Не посылать новый, пока старый не доставлен. Основная идея очень проста - при возникновении перегрузки не посылать новых пакетов. В ТСР это реализуется динамически с помощью механизма окон.

Прежде всего, как ТСР обнаруживает перегрузку - рост числа time out. Если эта величина превышает некоторый предел, являющийся параметром протокола, то это фиксируется как перегрузка. Причин может быть две - шум в канале, сброс пакетов маршрутизатором. Различить их сложно. В наши дни каналы достаточно надежные, так что остается вторая причина.

На рис.6-31 дана иллюстрация перегрузок. Это может быть по двум причинам. Нехватка буфера на стороне получателя - не достаточная емкость получателя. Перегрузка внутри сети - не достаточная емкость сети.

В Internet эти ситуации различаются как внутренняя емкость сети и емкость получателя. Поэтому каждый отправитель поддерживает два окна - обычное окно отправителя и окно перегрузки. Каждое показывает количество байтов, которое отправитель может послать. Фактически отправляемое количество - минимум из двух величин.

Сначала окно перегрузки полагают равным одному максимальному сегменту для данного соединения. Если сегмент успешно (без time out) был предан, то окно перегрузки увеличивается вдвое. Это увеличение будет происходить до тех пор, пока, либо не наступит time out и произойдет возврат к предыдущему значению, либо размер окна перегрузки не достигнет размера окна получателя. Этот алгоритм называется slow start - медленный старт.

Другой параметр управления перегрузками в Internet - порог (threshold). Алгоритм медленного старта при возникновении перегрузки устанавливает этот параметр равным половине длины окна перегрузки, а окно перегрузки устанавливает равным размеру максимального сегмента. Окно перегрузки растет экспоненциально до тех пор, пока не сравняется с порогом, после чего оно растет линейно, пока не достигнет размера окна получателя. На этом рост прекращается до первой перегрузки. Работа этого алгоритма показана на рис.6-32.

 

6.4.7.Управление таймером в TCP

Протокол ТСР использует несколько таймеров. Наиболее важный из них - таймер повторной передачи. Этот таймер устанавливают, когда сегмент посылают. Если подтверждение пришло до исчерпания этого таймера, то его останавливают. Если он исчерпан, то сегмент посылают повторно. Здесь основная проблема как удачно выбрать величину time out. Идея используемого алгоритма - вводится специальная переменная RTT(round trip time) , значение которой постоянно модифицируется, чтобы получить оптимальное значение time out. Если при очередной передаче подтверждение поступило прежде, чем наступил time out, значение этой переменной немного уменьшают, в противном случае - увеличивают. Были проведены специальные, тщательные исследования того, как это надо делать. Основное внимание уделяется измерению и анализу времени подтверждения сегмента, вычислению его среднего значения.

Другой важный таймер - таймер постоянства. Он позволяет бороться с тупиками следующего вида. Когда получатель послал сообщение с нулевым размером окна, отправитель останавливает передачу и ждет сообщения об изменении размера окна. Вот наконец, получатель послал это сообщение, а оно было потеряно. Все ждут. Чтобы избежать такой ситуации, используют таймер постоянства. Если он исчерпан, то отправитель шлет сообщение получателю, напоминая ему о проблеме размера буфера.

Другой важный таймер - таймер функционирования. Проблема здесь в том, что если по какой-либо причине по соединению долго не посылали сообщений, то надо проверить функционирует ли оно. Когда этот таймер исчерпан, то соответствующая сторона шлет другой стороне запрос "жива ли, ты". Если ответа не поступает, то соединение считается разорванным.

 

6.4.8.Протокол UDP

Internet поддерживает также транспортный протокол без соединений - UDP (User Data Protocol RFC768). Этот протокол инкапсулирует сегменты в виде дейтаграмм и шлет их через сеть. Структура UDP сегмента показана на рис.6-34.

 

6.4.9. TCP и UDP в беспроводных коммуникациях

Теоретически ТСР не должен зависеть над какой средой он работает - оптической или радио. Однако на практике дело обстоит иначе. ТСР протокол тщательно оптимизировали при разных предположениях, которые не выполняются в беспроводной среде.. Так, например, предполагалось, что сетевая среда достаточно надежна и рост числа time_out - это результат перегрузки, а не потери пакетов.

В беспроводной среде потеря пакета дело частое. Поэтому, применение ТСР "в лоб" с протоколом Якобсона медленного старта лишь усугубит положение. Так, например, если потери составляют 20%, то при пропускной способности канала в 100 пакет/сек, фактически будет лишь 80 пакет/сек. Согласно алгоритму медленного старта при увеличении числа time_out надо понизить скорость, скажем до 50 пакет/сек, что приведет к фактической скорости 40 пакет/сек.

Поэтому, если увеличилось число отказов в обычном канале, надо сбросить скорость, если это число возросло в беспроводной среде, надо не скорость понижать, а слать пакеты повторно. Так что без знания о среде, принять решение трудно.

Основным источником проблем является то, что в беспроводной среде соединения часто не однородные. На рис.6-35 показан пример. Была предложена модификация ТСР - разбить такое соединение на два, так что каждое стало однородным. Есть и другие решения, связанные с модификацией на самого ТСР, а канального уровня для базовых станций.

 

6.5.Транспортный уровень в ATM

 

6.6.Вопросы производительности

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

  1. Вопросы производительности
  2. Измерение производительности
  3. Влияние организации сетей на производительность
  4. Быстрая обработка TPDU
  5. Протоколы для высоко производительных сетей

 

6.6.1.Проблемы производительности в сетях

Одина из таких причин - перегрузки из-за несбалансированности ресурсов и нагрузки. Если на маршрутизаторы наваливается больше нагрузки, чем они могут переработать, возникает перегрузка. Перегрузки были достаточно подробно рассмотрены ранее.

Производительность может падать из-за структурной несбалансированности ресурсов. Например, если персональную машину подключить к Гигабитному каналу, то она будет захлебываться от наплыва пакетов из-за несбалансированности скорости ЦП и скорости канала.

Перегрузка может быть вызвана синхронно, как реакция на некоторые действия в сети. Это, так называемые, синхронные перегрузки. Например, если TPDU содержит неверный параметр (номер порта или процесс), то в ответ пойдет сообщение об ошибке. Если такой пакет получили сотни или тысячи машин, то в ответ последует ураган сообщений. Этой проблеме был подвержен протокол UDP до тех пор, пока не было внесено изменение в протокол разрешающее или запрещающее слать подтверждение. Другой пример - перезагрузка машин в сети после сбоя питания. Все машина разом ринуться на RARP сервер и файл сервер за надлежащей информацией. В результате - коллапс серверов.

Другая причина - настройка системы. Например, если машины в сети имеют достаточно мощные процессоры и достаточно памяти, но буфера в системе памяти выделено не достаточно. В результате пакеты будет теряться из-за переполнения буферов. Аналогично, если планировщик процессов в ОС не дает достаточно высокий приоритет процессу обработки TPDU, то пакеты будут теряться.

Другой параметр настройки - время time out. Если time out на подтверждение слишком короток, то много будет перепосылок, если - велик - скорость передачи упадет. Еще один пример - время ожидания попутного сообщения, с которым можно отправить подтверждение о полученном пакете. Если значение этого параметра мало, то будет много дополнительных пакетов-уведомлений. Если - велико, то получатель может генерировать запросы по time out, скорость передачи упадет.

Появление гигабитных сетей принесло новые причины потери производительности. Пусть мы хоти передать пакет из Москвы во Владивосток. Пусть у нас есть линия на 1 Гбит/сек, а у получателя буфер на 64К байт. Задержка на передачу в одном направлении по оптоволоконному каналу будет около 40 msec. Через 500 msec все 64К байт будут в канале и отправитель будет ждать подтверждения. В результате пропускная способность канала будет использована на 1,25%! Дело в том, что буфер у получателя надо устанавливать равным произведению пропускной способности канала на величину задержки. На самом деле он должен быть чуть больше. Получатель по какой-то причине может не сразу отреагировать на поступившие данные.

 

6.6.2.Измерение производительности в сети

Когда пользователи сети обнаруживают падение производительности их приложений, они идут к администратору сети с жалобами. Последний обязан выяснить, что случилось и принять необходимые меры. Типичная последовательность действий при исправлении производительности сети такова:

  1. Измерить надлежащие параметры сети и производительность;
  2. Постараться понять что происходит;
  3. Изменить один параметр.

Эти шаги надо повторять до тех пор, пока либо не удастся повысить производительность, либо не станет ясно, что имеющимися ресурсами этого сделать нельзя.

Измерения можно проводить в разных местах и разными способами. Основная идея всех измерений состоит в том, чтобы запустить какую-то активность и измерить как долго она продолжается, какие события ее сопровождают. Измерение длительности и сбор информации о событиях таят много подвохов. Ниже перечислены лишь некоторые из них.

Количество испытаний должно быть достаточно велико

Измерить время доставки одного TPDU не достаточно. Это надо проделать миллионы раз. Тогда вычисление среднего и дисперсии будет свободно от влияния случайных факторов. В курсе математической статистики можно посмотреть, как выполнять такие вычисления.

Выборка испытаний должна быть представительной

Проводить испытания надо в разное время дня и года. Что толку измерять производительность сети в университете в августе? Если измерения проводятся с 12 до 14, опять таки они не точны. В это время часто уходят на обед.

Надо учитывать разрешающую способность часов

Как правило, таймер машины работает от сети - 50 Гц. Поэтому измерять моменты наступления событий, происходящих чаще, чем через 20 msec им нельзя. Однако, если измерить интервал когда произошло миллион регулярных событий, то вычислив среднее мы получим нужное значение.

Ничего неожиданного во время измерений происходить не должно

Надо быть уверенным, что измерения происходят при "типичных" нагрузках. Нет единичных всплесков активности, например, лабораторных работ. Нельзя быть уверенным, что все "тихо" только потому, что измерения происходят в 3 часа утра. Хотя бы потому, что программа архивации работает именно по ночам.

Кэш память может разрушить ваши измерения

Пусть, например, мы хотим измерить время передачи файла. Для этого надо будет его открыть, передать, закрыть и измерить общее время. Сделать это надо будет много раз. Однако, если файл меньше размера кэш памяти, то мы будем измерять скорость кэш памяти и только первое измерение будет показывать производительность сети. Чтобы избежать этого эффекта, надо выбирать файлы достаточно большого размера.

Аналогичное влияние может оказывать буферизация. Например, если UDP получает подтверждение от сетевого уровня, как только сетевой уровень получил пакет и на сетевом уровне есть буфер на 1000 дейтаграмм, то проводя 999 испытаний мы получим скорость передачи выше, чем пропускная способность физического канала.

Надо четко осознавать, что вы измеряете

Когда Вы измеряете время чтения удаленного файла, то Ваши измерения зависят от сетевой среды, операционных систем клиента и сервера, их сетевых плат, драйверов и т.п. Если Вы хотите настроить взаимодействие при конкретной конфигурации, то Ваше измерение имеет смысл. Если эти измерения будут использованы для выбора сетевых карт, то собранные Вами данные не годятся. Например, может оказаться, что драйвер, используемый в измеряемой конфигурации, работает отвратительно с выбранной сетевой платой.

Надо быть очень осторожным при экстраполяции результатов

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

 

6.6.3.Правила, улучшающие производительность

Повышать производительность существующей сети можно лишь в определенных пределах. Куда большие возможности для этого есть при проектировании сети. Здесь будут перечислены некоторые правила, сформулированные чисто на опыте создания многих сетей.

Правило 1: Скорость процессора важнее, чем скорость сети

Опыт показал, что накладные расходы на работу операционной системы и стека протоколов значительно больше, чем накладные расходы при передаче по физическому каналу. Теоретические RPC на Ethernet должно занимать не более 102 msec. На практике редко его удается снизить до 1500 msec. Основные задержки в системном программном обеспечении.

Аналогично, при использовании высоко скоростных каналов важно повысить скорость доставки байта до канала и его обработку при получении. Другими словами, удвоив скорость процессора на хосте, можно удвоить пропускную способность сети. Удвоив емкость сети, можно ничего не получить так как узким местом будет программное обеспечение хоста. 

Правило 2: Понижай число пакетов, чтобы сократить накладные расходы программного обеспечения

При обработке TPDU часть накладных расходов приходиться на обработку самого TPDU, на пример, заголовка пакета, а часть на обработку байтов TPDU, на пример подсчет контрольных сумм. Поэтому, посылая TPDU в 128 байт, мы в 32 раза увеличиваем накладные расходы, чем если бы мы использовали TPDU в 4К.

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

Правило 3: Минимизируй переключение контекста

Минимизировать переключения контекста удается с помощью специальных процедур, позволяющих накапливать пакеты и сообщения в буферах, прежде чем передавать их процессу более высокого уровня.

Правило 4: Минимизируй число копий

Куда больший ущерб производительности, чем переключение контекста, наносит множественное копирование одного и того же пакета. Обычно, пакет принятый сетевым интерфейсом буферизуют на сетевой плате, потом в ядре на сетевом уровне, затем в буфере транспортного уровня и, лишь потом в буфере приложения!

Хорошая операционная система буферизует пословно. Однако. типично операция буферизации занимает на менее 5 команд на слово. При процессоре 50 MIPS создание трех копий при пяти командах на 32 битовое слово потребует 74 nsec. Таким образом, максимальная скорость приема данных будет не более 107 Mbps. Учитывая обработку заголовков, прерываний, переключение контекстов, получим не более 50 Mbps. Очевидно, что и речи быть не может о работе с таким процессором на линии в 1Gbps.

Отметим так же, что 50 Mbps это скорость без учета обращений в память. С учетом памяти она будет раза в три меньше, около 16 Mbps.

Правило 5: Увеличение пропускной способности, не сократит задержку

Если Вам нужна пропускная способность, Вы можете купить ее, например, проложив еще один кабель. Однако, это не сократит задержку при передачи. Это требует улучшения программного обеспечения стека протоколов, системного программного обеспечения и сетевых интерфейсов.

Правило 6: Лучше избегать перегрузок, чем восстанавливаться после них

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

Правило 7: Избегайте наступления time out

Таймеры неизбежны в сетях. Однако, использовать их надо очень аккуратно и минимизировать их исчерпание (time out). Поскольку их исчерпание влечет выполнение специальных действий. Поэтому установка таймера требует тщательных измерений, а изменение начального значения надо делать очень осторожно и постепенно.

 

6.6.4.Быстрая обработка TPDU

 

6.7.Протоколы для гигабитных сетей