А. Робачевский - Операционная система UNIX (1114671), страница 80
Текст из файла (страница 80)
Однако согласно RFC"Requirements for Internet Hosts — Communication Layers", модуль TCPПредполагается, что получатель подтверждает каждый сегмент. На самом деле это не так, и вэтом случае приращение производится фактически на число подтвержденных сегментов.Ⱦɚɧɧɚɹɜɟɪɫɢɹɤɧɢɝɢɜɵɩɭɳɟɧɚɷɥɟɤɬɪɨɧɧɵɦɢɡɞɚɬɟɥɶɫɬɜɨɦ%RRNVVKRSɊɚɫɩɪɨɫɬɪɚɧɟɧɢɟɩɪɨɞɚɠɚɩɟɪɟɡɚɩɢɫɶɞɚɧɧɨɣɤɧɢɝɢɢɥɢɟɟɱɚɫɬɟɣɁȺɉɊȿɓȿɇɕɈɜɫɟɯɧɚɪɭɲɟɧɢɹɯɩɪɨɫɶɛɚɫɨɨɛɳɚɬɶɩɨɚɞɪɟɫɭpiracy@books-shop.com420Глава 6.сети в операционной системе UNIXможет отправить немедленное подтверждение при получении неупорядо!ченных сегментов.
Цель такого подтверждения — уведомить отправителя,что был получен неупорядоченный сегмент, и указать порядковый номерожидаемых данных. Поскольку ожидаемый порядковый номер осталсяпрежним (получение неупорядоченного сегмента не изменит его значе!ние), данное подтверждение может явиться дубликатом уже отправленногоранее.Таким образом, получение дублированных подтверждений может быть вы!звано двумя причинами: потерей сегмента, как следствием затора в сети, иполучением неупорядоченного сегмента.
Чтобы установить истинную при!чину, модуль TCP ждет получения еще нескольких дублированных под!тверждений. Если причина в получении неупорядоченного сегмента, вы!званном буферизацией на промежуточных шлюзах или различными путя!ми передачи датаграмм, то, вероятнее всего, вскоре ожидаемый сегментбудет получен и порядок будет восстановлен, что выразится в получениинового (уже не дубликата) подтверждения. Если получено три или болеедубликатов, следует полагать, что произошла потеря данных. В этом слу!чае отправитель совершает повторную передачу утраченного сегмента.
Этапроцедура получила название быстрой повторной передани (fast retransmit).При этом, включается механизм устранения затора, но не медленныйстарт. Причиной такого поведения является то, что получение сегмента,хотя и не упорядоченного, свидетельствует об относительно невысокомуровне переполнения в сети, и необходимость в столь радикальных мерах,как медленный старт, отсутствует.Однако потеря данных может вызвать ответное молчание. Для обработкиподобной ситуации отправитель должен установить таймер и повторно пе!редать данные по тайм!ауту, начиная с последнего подтверждения. Дан!ный механизм является запасным и гарантирует повторную передачу, хотяи вызывает довольно большие задержки.Программные интерфейсыПрограммный интерфейс сокетовВы уже познакомились с интерфейсом сокетов при обсуждении реализа!ции межпроцессного взаимодействия в BSD UNIX.
Поскольку сетеваяподдержка впервые была разработана именно для BSD UNIX, интерфейссокетов и сегодня является весьма распространенным при создании сете!вых приложений. В разделе "Поддержка сети в BSD UNIX" мы вновь вер!немся к сокетам, когда будем рассматривать внутреннюю архитектуру се!тевой подсистемы в UNIX ветви BSD. Сейчас же рассмотрим простойпример приложения клиент!сервер, который демонстрирует возможностисокетов при обеспечении взаимодействия между удаленными процессами.Несмотря на то что взаимодействие затрагивает передачу данных по сети,www.books-shop.comПрограммные интерфейсыприведенная программа мало отличается от примера, рассмотренного вразделе "Межпроцессное взаимодействие в BSD UNIX.главы 3.Логика приложения сохранена — клиент отправляет серверу сообщение,сервер передает его обратно, а клиент, в свою очередь, выводит получен!ное сообщение на экран.
Наиболее существенным отличием являетсякоммуникационный домен сокетов — в данном случае AF_INET. Соответ!ственно изменилась и схема адресации коммуникационного узла. Соглас!но схеме адресации TCP/IP, коммуникационный узел однозначно иденти!фицируется двумя значениями: адресом хоста (IP!адрес) и адресом про!цесса (адрес порта).
Это отражает и структуракоторая явля!ется конкретным видом общей структуры адреса сокета sockaddr. Струк!тура sockaddr_in имеет следующий вид:structshortu_shortstructchar{Номер портаIPадрес хостаАдрес порта должен быть предварительно оговорен между клиентом и сер!вером.В заключение, прежде чем перейти непосредственно к текстам программы,заметим, что интерфейс сокетов также поддерживается и в UNIX SystemV, наряду с другим программным интерфейсом — ТЫ, который будет рас!смотрен в следующем разделе.Приведенный пример в качестве транспортного протокола используетTCP. Это значит, что перед передачей прикладных данных клиент долженустановить соединение с сервером.
Эта схема, приведенная на рис. 6.17,несколько отличается от рассмотренной в разделе "Межпроцессное взаи!модействие в BSD UNIX. Сокеты", где передача данных осуществляласьбез предварительного установления связи и в данном случае соответство!вала бы использованию протокола UDP.В соответствии с этой схемой сервер производит связывание с портом,номер которого предполагается известным для клиентови сооб!щает о готовности приема запросовПри получении запроса он спомощью функции accept(2) создает новый сокет, который и обслуживаетобмен данными между клиентом и сервером.
Для того чтобы сервер могпродолжать обрабатывать поступающие запросы, он порождает отдельныйпроцесс на каждый поступивший запрос. Дочерний процесс, в свою оче!редь, принимает сообщения от клиентаи передает их обратноКлиент не выполняет связывания, поскольку ему безразлично, какой адресбудет иметь его коммуникационный узел. Эту операцию выполняет систе!www.books-shop.com422Глава 6.сети в операционнойUNIXма, выбирая свободный адрес порта и установленный адрес хоста. Далееклиент направляет запрос на установление соединенияуказы!вая адрес сервера (IP!адрес и номер порта). После установления соедине!ния ("тройное рукопожатие") клиент передает сообщениеприни!мает от сервера ответи выводит его на экран.Рис.
6.17. Схема установления связи и передачи данных между клиентом и серверомВ программе используются несколько функций, которые не рассматрива!лись. Эти функции значительно облегчают жизнь программисту, выпол!няя, например, такие действия, как трансляцию доменного имени хоста вего IP!адресприведение в соответствие порядка следо!вания байтов в структурах данных, который может различаться для хоста исетиа также преобразование IP!адресов и их составных частейв соответствии с привычной "человеческой" нотацией, напримерМы не будем подробнее останавливаться на этих функци!www.books-shop.comПрограммные интерфейсы423ях, предоставляя читателю самостоятельно обратиться к соответствующимразделам электронного справочникаНиже приведены тексты программ сервера и клиента.Серверftincludelincludeftinclude <stdio.h><fcntl.h><netdb.h>/*Номер порта сервера, известный#define1500argv)intchar{int s, ns;int pid;int nport;struct sockaddr_in serv_addr,struct hostentchar/*Преобразуем порядок следования байтов к сетевомуnport = PORTNUM;nport =/*Создадим сокет, использующий протоколSOCK_STREAM,{вызова}/*3ададим адрес коммуникационного===/*Свяжем сокет с этимsockaddr{вызова}сообщение с указанием адреса"Сервер/*Сервер готов принимать запросы на установление соединения.Максимальное число запросов, ожидающих обработки 5.
Как правило,www.books-shop.com424Глава 6.сети в операционной системе UNIXэтого числа достаточно, чтобы успеть выполнитьпородить дочернийи{вызова}цикл получения запросов и ихwhile (1){int addrlen;addrlen =/*Примем запрос. Новый сокет ns становится коммуникационным узломсозданного виртуального(struct sockaddr{вызова accept}информацию о"Клиент =/*Создадим процесс для работы с{вызова}{int nbytes;intэтот сокет нам неОн попрежнемуиспользуется для полученияclose/*Получим сообщение от клиента и передадим егоwhile= recv(ns, buf,!=0){buf,0);}exit (0)}этот сокет нам не нужен.
Он используетсядочерним процессом для обмена}www.books-shop.comинтерфейсы425Клиентttinclude<stdio.h><fcntl.h><netdb.h>idefineпорта, который обслуживается1500argv)charint{int sintint;struct sockaddr_instruct hostentchar/*B качестве аргумента клиенту передается доменное имя хоста, накотором запущен сервер. Произведем трансляцию доменного имени в{вызова}==/*Создадим сокет*/{вызова}"Адрес/*Создадим виртуальныйif(struct sockaddr{вызова}/*0тправим серверу сообщение и получим егоbuf,www.books-shop.com426Глава 6.вUNIXif (recv(s, buf, sizeof(buf), 0) <0){вызова}полученное сообщение наот сервера:closeзавершил работу}Программный интерфейс TLIПри обсуждении реализации сетевой поддержки в BSD UNIX был рас!смотрен программный интерфейс доступа к сетевым ресурсам, основан!ный наВ данном разделе описан интерфейс транспортного уровня(Transport Layer Interface, TLI), который обеспечивает взаимодействиеприкладных программ с транспортными протоколами.ТЫ был впервые представлен в UNIX System V Release 3.0 в 1986 году.Этот программный интерфейс тесно связан с сетевой подсистемой UNIX,основанной на архитектуре STREAMS, изолируя от прикладной програм!мы особенности сетевой архитектуры.
Вместо того чтобы непосредственнопользоваться общими функциями STREAMS, рассмотренными в преды!дущей главе, ТЫ позволяет использовать специальный набор вызовов,специально предназначенных для сетевых приложений. Для преобразова!ния вызовов ТЫ в функции интерфейса STREAMS используется библио!тека ТЫ, которая в большинстве систем UNIX имеет название libnsl.a илиСхема использования функций ТЫ во многом сходна с рассмотренныминтерфейсом сокетов и зависит от типа используемого протокола —с предварительным установлением соединения (например, TCP) или безнего (например, UDP).На рис. 6.18 и 6.19 представлены схемы использования функций ТЫ длятранспортных протоколов с предварительным установлением соединенияи без установления соединения. Можно отметить, что эти схемы оченьпохожи на те, с которыми мы уже встречались в разделе "Межпроцессноевзаимодействие в BSD UNIX.главы 3 при обсуждении сокетов.Некоторые различия отмечены ниже при описании функций ТЫ.Прежде чем перейти к обсуждению функций ТЫ, остановимся на опреде!лении адреса коммуникационного узла.