Nets2010 (1131259), страница 47
Текст из файла (страница 47)
Другое важное различие между сетевым и транспортным сервисами состоит в том, кто их использует. Сетевой сервис использует транспортный сервис, а вот транспортный использует пользователь, т.е. прикладные программы. Поэтому транспортный сервис должен быть ориентирован на пользователя, удобным и простым в использовании.
Таблица 6-3. Примитивы транспортного сервиса
Примитив | Отправляемый пакет TPDU | Значение |
LISTEN | (нет) | Блокировка, пока какой-либо процесс не попытается установить соединение |
CONNECT | CONNECTION REQ. | Активная попытка установить соединение |
SEND | SEND | Информация об отправке |
RECEIVE | (нет) | Блокировка до поступления DATA TPDU |
DISCONNECT | DISCONNECTION REQ. | Данная сторона собирается прервать соединение |
Использование этих примитивов может быть продемонстрировано следующим образом. Сервер приложения выполняет примитив LISTEN, в результате чего он блокируется до поступления запросов от клиентов. Клиент для установления соединения выполняет примитив CONNECT. Транспортный агент на стороне клиента блокирует клиента и посылает серверу пакет с запросом на установление соединения.
Напомним, что транспортные агенты обмениваются пакетами, которые имеют специальное название - Transport Protocol Data Unit (TPDU).
Рисунок 6-4. Взаимосвязь между кадрами, пакетами и TPDU
По примитиву CONNECT транспортный агент на стороне клиента шлет CONNECTION REQUEST TPDU. Транспортный агент сервера, видя, что сервер заблокирован по LISTEN, разблокирует сервер и посылает CONNECTION ACCEPTED TPDU. После этого транспортное соединение считается установленным и начинается обмен данными с помощью примитивов SENT и RECEIVE.
По окончании обмена соединение должно быть разорвано. Есть два варианта разрыва соединения: симметричный и асимметричный. Асимметричный разрыв предполагает, что для разрыва соединения одна из сторон посылает DISCONNECT TPDU. Получив этот TPDU, другая сторона считает соединение разорванным.
При симметричном разрыве каждое направление закрывается отдельно. Когда одна сторона посылает DISCONNECT TPDU, это значит, что с ее стороны больше данных не будет. На рисунке 6-5 показана диаграмма состояний при установлении и разрыве соединения. (Переходы, выделенные курсивом, вызываются прибытием пакета. Пунктирной линией обозначена последовательность состояний сервера, сплошной - клиента.)
Рисунок 6-5. Диаграмма состояний при установлении и разрыве соединения
В таблице 6-6 показан другой набор примитивов, так называемые сокеты Беркли. В этом наборе два основных отличия от того, что мы только что рассмотрели. Первые четыре примитива выполняются сервером в том порядке, как они указаны в таблице. Примитив SOCKET создает новую точку подключения к серверу, резервирует для нее место в таблице транспортного агента. Параметры обращения определяют формат адреса, тип желаемого сервиса, протокол и т.д. По примитиву BIND сервер выделяет сокету адрес. Причина, по которой адрес выделяется не сразу, в том, что некоторые процессы сами управляют своими адресами, которые жестко закреплены за ними. Второе – LISTEN - не блокирующий примитив. Он выделяет ресурсы и создает очередь, если несколько клиентов будут обращаться за соединением в одно и то же время. Примитив ACCEPT - блокирующий в ожидании запроса на соединение.
Таблица 6-6. Сокеты Беркли
Примитив | Значение |
SOCKET | Создание новой точки подключения |
BIND | Прикрепление локального адреса к сокету |
LISTEN | Объявление готовности принимать соединения; сообщение о размере очереди |
ACCEPT | Блокировка вызывающего в ожидании запроса на соединение |
CONNECT | Активная попытка установить соединение |
SEND | Отправка данных через данное соединение |
RECEIVE | Получение данных через данное соединение |
CLOSE | Прерывание соединения |
Когда клиент выполняет примитив CONNECT, он блокируется своим транспортным агентом, и запускается процесс установления соединения. Когда он закончится, клиента разблокируют, и начинается обмен данными с помощью примитивов SEND и RECEIVE. Разрыв соединения здесь симметричен, т.е. соединение считается разорванным, если обе стороны выполнили примитив CLOSE.
Элементы транспортного протокола.
Транспортный сервис реализует транспортный протокол, который используют транспортные агенты. Транспортный протокол в чем-то схож с канальным. Однако между ними несколько различий:
-
Они работают в разных средах (см. рисунок 6-7).
-
Процессы на канальном уровне взаимодействуют непосредственно через физическую среду, поэтому процедура установления соединения много проще.
-
Среда, в которой работает транспортный протокол, использует память, которая может терять свое содержимое.
-
Количество соединений, которое может возникать на транспортном уровне, намного больше, чем количество соединений на канальном уровне, что создает дополнительные проблемы для буферизации и управления потоком.
Транспортный протокол должен решать следующие проблемы:
-
Как адресовать прикладной процесс, с которым надо установить соединение?
-
Как корректно установить соединение? Пакеты могут теряться. Как отличить пакеты нового соединения от повторных пакетов, оставшихся от старого?
-
Как корректно разрывать соединение?
Адресация.
Проблема адресации состоит в том, как указать, с каким удаленным прикладным процессом надо установить соединение. Обычно для этого используется транспортный адрес, по которому прикладной процесс может слушать запросы на соединение. Вместо него мы будем здесь использовать термин TSAP - Transport Service Access Point. Аналогичное понятие существует и на сетевом уровне - IP-адрес - NSAP для сетевого уровня.
На рисунке 6-8 показана взаимосвязь ТSAP и NSAP. Он же иллюстрирует сценарий использования ТSAP для установления соединения между двумя удаленными процессами.
Рисунок 6-8. Взаимодействие TSAP и NSAP
Из этой иллюстрации не ясно лишь, как прикладной процесс на машине 1 узнает, что интересующий его сервер подключен к ТSAP 122 на машине 2? Одно из возможных решений - если данный сервер всегда подключен к ТSAP 122, и все процессы об этом знают.
Такое решение хорошо работает для часто используемого сервиса с длительным периодом активности, но как быть прикладным процессам пользователя, которые активизируются спорадически на короткое время? В операционной системе Unixиспользуется решение, которое называется протоколом установления начального соединения. На каждой машине есть специальный сервер процессов, который представляет все процессы, исполняемые на этой машине. Этот сервер слушает несколько ТSAP, куда могут поступить запросы на ТСР-соединение. Если нет свободного сервера, способного выполнить запрос, то соединение устанавливается с сервером процессов, который переключит соединение на нужный сервер, как только он освободится.
Однако есть случаи, когда этот подход с сервером процессов не работает. Не всегда можно запускать сервер сервиса по требованию пользователя. Например, файловый сервер. Он должен существовать всегда. Решение в этом случае - сервер имен. Пользователь устанавливает соединение с сервером имен, для которого ТSAP известен, и передает ему имя сервиса. В ответ сервер имен шлет надлежащий ТSAP. Клиент разрывает соединение с сервером имен и устанавливает его по полученному адресу.
Пусть пользователь узнал ТSAP, но как он узнает, на какой машине этот ТSAP расположен, какой сетевой адрес надо использовать? Ответ заключается в структуре ТSAP-адреса, где указана вся необходимая информация. Этот адрес имеет иерархическую структуру.
Установление соединения.
Проблема установления транспортного соединения сложна потому, что пакеты могут теряться, храниться и дублироваться на сетевом уровне.
Типичный пример - установление соединения с банком для перевода денег с одного счета на другой. Из-за перегрузки в сети или по какой-либо другой причине может произойти большая задержка. Тогда по time_out активная сторона вышлет еще один запрос. Пакеты-дубли могут вызвать повторное соединение и вторичный перевод денег. Как быть?
Одно из возможных решений - временное ТSAP. После того, как оно использовано, TSAP с таким адресом более не возникает. При этом решении не работает модель с сервером процессов, когда определенные TSAP имеют фиксированные адреса.
Другое решение - каждому транспортному соединению сопоставлять уникальный номер. Когда соединение разрывается, этот номер заносится в специальный список. К сожалению, этот список может расти бесконечно. Кроме этого, в случае сбоя машины он может быть потерян, и тогда...
Альтернативой может быть ограничение времени жизни пакетов. Достичь этого можно тремя путями:
-
ограничением конструкции подсети
-
установкой счетчиков скачков в каждом пакете
-
установкой временной метки на каждом пакете
Заметим, что последний метод требует синхронизации маршрутизаторов в сети.
На практике нам надо обеспечить, чтобы стали недействительными не только сами пакеты, но и уведомления о них. Это значит, что надо ввести величину Т – множитель для максимального, реального времени жизни пакета в сети. Его конкретное значение зависит от конкретного протокола и позволяет немного увеличить реальное время жизни так, чтобы по его истечении в сети не осталось ни самого пакета, ни уведомления о нем.
При ограничении времени жизни пакета можно построить безопасный способ установления соединения. Этот метод был предложен Томлинсоном (Tomlinson). Его идея состоит в следующем. Все машины в сети оснащены таймерами. Таймер работает даже в случае сбоя машины, т.е. он абсолютно надежен. Каждый таймер - двоичный счетчик достаточно большой разрядности, равной или превосходящей разрядность последовательных чисел, используемых для нумерации пакетов. При установлении соединения значения нескольких младших разрядов этого таймера берутся в качестве начального номера пакета. Главное, чтобы последовательности номеров пакетов одного соединения не приводили к переполнению счетчика и его обнулению. Эти номера можно также использовать для управления потоком в протоколе скользящего окна.
Проблема возникает, когда машина восстанавливается после сбоя. Транспортный агент не знает в этот момент, какое число можно использовать для очередного номера. Чтобы избежать повторного использования порядкового номера, который уже был сгенерирован перед сбоем машины, вводится специальная величина по времени, которая образует область запрещенных номеров (см. рисунок 6-10).
Рисунок 6-10. (а) TPDU не могут попасть в запрещенную область; (b) Проблема ресинхронизации
Машина, восстановленная после сбоя, не может выбирать номера из этой запретной зоны. Поэтому после восстановления следует подождать Т сек., пока все ранее посланные пакеты не перестанут существовать. На практике поступают иначе, чтобы не тратить впустую эти Т сек. Строят кривую скорости генерации номеров n=at, тогда после сбоя надо выбирать номера по формуле: n=at+T.
Проблема номеров может возникать по двум причинам. Либо потому, что машина генерирует слишком быстро пакеты и соединения, либо потому, что делает это слишком медленно. Чем больше разрядность счетчика последовательных номеров, тем дальше отодвигается момент попадания в запретную область.
Другая нетривиальная проблема - надежное установление соединения: пакеты ведь могут пропадать. Для ее решения Томлинсон предложил процедуру «троекратного рукопожатия» (three-way handshake). Эта процедура предполагает, что машина 1 шлет запрос на установление соединения под номером x. Машина 2 шлет подтверждение на запрос x, но со своим номером у. Машина 1 подтверждает получение подтверждения с номером у. На рисунке 6-11 (b) и (c) показано, что будет, если поступит запоздавший запрос на соединение и запрос и подтверждение на него.