Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Малышев_Сетевое программирование 19.12.18

.pdf
Скачиваний:
2
Добавлен:
21.11.2025
Размер:
896.22 Кб
Скачать

21

3.4. НЕБЛОКИРУЮЩИЙ РЕЖИМ

Работа неблокирующих сокетов основана на системных событиях. После того как произведен вызов, будет возбуждено событие [7].

Например, также вызывается метод Connect, который немедленно возвращает управление в основную программу. Когда сокет будет подсоединен, то будет возбуждено событие, на которое должна отреагировать основная программа. Это требует, что бы логика связи была разделена по многим процедурам или нужно использовать циклы опроса, чтоб не пропустить событие.

Достоинства неблокирующего режима

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

Многозадачность без использования потоков – используется един-

ственный кодовый поток для обработки множества сокетов.

Очень малая нагрузка при множестве сокетов – поскольку множе-

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

Недостаток неблокирующего режима

Более сложное программирование – неблокирующие сокеты требу-

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

3.5.СРАВНЕНИЕ РЕЖИМОВ

Для тех, кто никогда не программировал сокеты до использования компонентов Indy, то будет легко и естественно использовать их. Но для тех, кто программировал сокеты ранее, использовать Indy будет сложно, так как Indy работает совсем по-другому. Это не означает, что другие решения неправильные, просто Indy работает иначе. Пытаться программировать в Indy так же, как с другими сокетными библиотеками, приведет к неправильному результату [7].

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

22

кетами в основном в скорости доступа. Доступ к файлу не всегда быстрый. Накопители информации часто имеют медленную скорость.

Представим простой сценарий записи в файл:

1)открыть файл;

2)записать данные;

3)закрыть файл.

Блокирующая запись в файл выглядит следующим образом: procedure TForm1.Button1Click(Sender: TObject);

var

s: string; begin

s := 'Indy Rules the (Kudzu) World !' + #13#10; try

// Open the file

with TFileStream.Create('c:\temp\test.dat', fmCreate) do try

//Write data to the file WriteBuffer(s[1], Length(s));

//Close the file

finally Free; end; end; end;

Как видно, код последовательный и легкий для понимания.

Не существует такой вещи как неблокирующий режим записи файла (исключая overlapped I/O), но здесь можно просто эмулировать этот механизм. File1 – это условный неблокирующий компонент, размещенный на форме.

procedure TForm1.Button1Click(Sender: TObject); begin

File1.Filename := 'd:\temp\test.dat'; File1.Open;

end;

procedure TForm1.File1OnOpen(Sender: TObject); var

i: integer; begin

FWriteData := 'Hello World!' + #13#10; i := File1.Write(FWriteData); Delete(FWriteData, 1, i);

end;

23

procedure TForm1.File1OnWrite(Sender: TObject); var

i: integer; begin

i := File1.Write(FWriteData); Delete(FWriteData, 1, i);

if Length(FWriteData) = 0 then begin

File1.Close;

end;

end;

procedure TForm1.File1OnClose(Sender: TObject); begin

Button1.Enabled := True; end;

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

1)При вызове Button1Click открывается файл. Метод Open немедленно вернет управление в программу, но файл еще не открыт и с ним еще нельзя работать.

2)Обработчик события OnOpen будет возбужден, когда файл будет открыть и готов к работе. Делается попытка записать данные в файл, но все данные еще не акцептированы. Метод Write вернет количество записанных байт. Оставшиеся данные будут сохранены позже.

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

4)Шаг 3 повторяется до тех пор, пока все данные не будут записаны методом Write. По окончанию записи всех данных вызывается метод Close. Но файл пока еще не закрыт.

5)Событие OnClose запускается, файл теперь закрыт.

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

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

Неблокирующая версия более сложная и более тяжелая для понимания. Однако, почти все сокетные функции используют неблокирующий режим [7].

24

Использование Indy почти равносильно использованию файлов. В действительности Indy еще проще, поскольку Indy имеет ряд методов для чтения и записи. Indy-пример, эквивалентный примеру с файлами выглядит так:

with IndyClient do begin

Connect; Try

WriteLn('Hello World.'); finally

Disconnect;

end;

end;

Как можно видеть, использование Indy в действительности очень похоже на работу с файлами. Метод Connect замещает функцию Open, а метод Disconnect замещает функцию Close. Если применять сокеты как чтение и запись в файл, то использовать Indy будет очень просто.

4. ПЛОСКИЕ ИМЕНА, ДОМЕННЫЕ ИМЕНА И IP-АДРЕСА

Для идентификации компьютеров аппаратное и программное обеспечение в сетях TCP/IP использует IP-адреса, поэтому для доступа к сетевому ресурсу в параметрах программы необходимо указать IP-адрес, чтобы программа правильно поняла, к какому компьютеру ей нужно обратиться. Например, команда ftp://192.45.66.17 будет устанавливать сеанс связи с ftp-сервером по данному IP-адресу, а команда http://203.23.106.33 откроет начальную страницу на Web-сервере с указанным IP-адресом. Однако пользователи обычно предпочитают работать не с цифровыми IP- адресами, а с символьными именами компьютеров, и операционные системы используют этот способ [4].

В операционных системах, которые первоначально разрабатывались для работы в локальных сетях, таких как Novell NetWare, Microsoft Windows или IBM OS/2, пользователи работали с обычными символьными именами компьютеров. Так как локальные сети состояли из небольшого числа компьютеров, то использовались так называемые плоские имена, состоящие из последовательности символов, не разделенных на части. Примерами таких имен являются: VS-417-4, VS1, NW1_1, mail2, MOSCOW_SALES_2. Для установления соответствия между этими символьными именами и МАС-адресами в этих операционных системах применялся механизм широковещательных запросов, подобный современному

25

механизму запросов протокола ARP. Также широковещательный способ разрешения имен реализован в NetBIOS, на котором были построены многие локальные ОС. Так называемые NetBIOS-имена стали на долгие годы одним из основных типов плоских имен в локальных сетях. Компания Microsoft для своих корпоративных операционных систем, начиная с Windows NT, разработала централизованную службу WINS, которая поддерживает базу данных NetBIOS-имен и соответствующих им IP-адресов.

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

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

2)Широковещательный способ установления соответствия между символьными именами и локальными адресами хорошо работает только в небольшой локальной сети, не разделенной на подсети. В крупных сетях, где общая широковещательность не поддерживается, нужен другой способ разрешения символьных имен. Обычно хорошей альтернативой широковещательности является применение централизованной службы, поддерживающей соответствие между различными типами адресов всех компьютеров сети [4].

Для эффективной организации именования компьютеров в больших сетях естественным также является применение иерархических составных имен. В стеке TCP/IP применяется централизованная доменная система имен (DNS-имена), которая имеет иерархическую древовидную структуру

спроизвольным количеством составных частей в имени (рис. 3).

26

Рис. 3. Пространство доменных имен

Полное доменное имя состоит из доменов, разделенных точками. Иерархия доменных имен аналогична иерархии имен файлов, приня-

той во многих популярных файловых системах. Дерево имен начинается с корня, обозначаемого здесь точкой (.). Затем следует старшая символьная часть имени, вторая по старшинству символьная часть имени и т. д. Младшая часть имени соответствует конечному узлу сети. В отличие от имен файлов, при записи которых сначала указывается самая старшая составляющая, затем составляющая более низкого уровня и т. д., запись доменного имени начинается с самой младшей составляющей (домен нижнего уровня), а заканчивается самой старшей (домен верхнего уровня). Составные части доменного имени отделяется друг от друга точкой. Например, в имени www.microsoft.com составляющая www является именем одного из компьютеров (веб-сервера) в доменной сети microsoft.com.

Компьютеры, входящие в домен, в соответствии со своими составными именами могут иметь совершенно различные IP-адреса, принадлежащие к различным сетям и подсетям. Например, в домен mgu.ru могут входить компьютеры с адресами 132.13.34.15, 201.22.100.33,14.0.0.6.

Доменная система имен реализована в сети Internet, но может работать и как автономная система имен в корпоративной сети, не связанной с Internet’ом, но использующей стек TCP/IP.

В Internet’е корневой домен управляется центром InterNIC (регистратор доменов в .com, .net, .org (www.internic.net)). Домены верхнего уровня назначаются для каждой страны (географический принцип построения), а

27

также на организационной основе. Имена этих доменов должны следовать международному стандарту ISO 3166 [4].

Каждый домен администрируется отдельной организацией, которая обычно разбивает свой домен на поддомены и передает функции администрирования этих поддоменов другим организациям. Чтобы получить доменное имя (например, для своего сайта), необходимо зарегистрироваться в какой-либо организации, которой InterNIC делегировал свои полномочия по распределению имен доменов. В России такой организацией является РосНИИРОС, которая отвечает за делегирование имен поддоменов в доменах ru, .рф (RIPN, www.ripn.net). Географический домен для какого-либо города может вести крупный провайдер, находящийся в этом городе.

Домены третьего и ниже уровней обычно предоставляются пользователю бесплатно.

Соответствие между доменными именами и IP-адресами может устанавливаться как средствами локального компьютера, так и средствами централизованной службы. На раннем этапе развития Internet’а на каждом компьютере вручную создавался текстовый файл с известным именем hosts. Этот файл состоял из некоторого количества строк, каждая из которых содержала одну пару "IP-адрес – доменное имя", например 102.54.94.97 – rhino.acme.com. Файл выкладывался на FTP-сервер и пользователи могли его скачать.

По мере роста Internet файлы hosts также росли, и создание масштабируемого решения для разрешения имен стало необходимостью.

Для этого в сетях TCP/IP существует механизм для установления соответствия между символьными именами и IP-адресами

Таким решением в начале 80-х г. г. стала специальная служба – система доменных имен (Domain Name System, DNS). DNS – это централизованная служба, основанная на распределенной базе отображений "доменное имя – IP-адрес". DNS-серверы поддерживают распределенную базу отображений, а клиенты обращаются к серверам с запросами о разрешении доменного имени в IP-адрес.

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

Для каждого домена имен создается свой DNS-сервер. Этот сервер может хранить отображения "доменное имя – IP-адрес" для всего домена, включая все его поддомены, либо чаще сервер домена хранит только име-

28

на, которые заканчиваются на следующем ниже уровне иерархии по сравнению с именем домена. (Аналогично каталогу файловой системы, который содержит записи о файлах и подкаталогах, непосредственно в него "входящих".) Именно при такой организации службы DNS нагрузка по разрешению имен распределяется более-менее равномерно между всеми DNS-серверами сети. Например, в первом случае DNS-сервер домена mmt.ru будет хранить отображения для всех имен, заканчивающихся на mmt.ru: wwwl.zil.mmt.ru, ftp.zil.mmt.ru, mail.mmt.ru и т. д. Во втором случае этот сервер хранит отображения только имен типа mail.mmt.ru, www.mmt.ru, а все остальные отображения должны храниться на DNS- сервере поддомена zil.

Каждый DNS-сервер кроме таблицы отображений имен содержит ссылки на DNS-серверы своих поддоменов (на IP-адреса соответствующих серверов) и DNS-сервер более выскокого уровня.

Для обслуживания корневого домена выделено несколько дублирующих друг друга DNS-серверов, IP-адреса которых являются широко известными (их можно узнать, например, в InterNIC).

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

Существуют две основные схемы разрешения DNS-имен. В первом варианте работу по поиску IP-адреса координирует DNS-клиент:

-DNS-клиент обращается к корневому DNS-серверу с указанием полного доменного имени;

-DNS-сервер отвечает, указывая адрес следующего DNS-сервера, обслуживающего домен верхнего уровня, заданный в старшей части запрошенного имени;

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

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

Во втором варианте реализуется рекурсивная (косвенная) процедура:

-DNS-клиент запрашивает локальный DNS-сервер, то есть тот сервер, который обслуживает поддомен, к которому принадлежит имя клиента;

29

-если локальный DNS-сервер знает ответ, то он сразу же возвращает его клиенту; это может соответствовать случаю, когда запрошенное имя входит в тот же поддомен, что и имя клиента, а также может соответствовать случаю, когда сервер уже узнавал данное соответствие для другого клиента и сохранил его в своем кэше;

-если же локальный сервер не знает ответ, то он выполняет итеративные запросы к корневому серверу и т. д. точно так же, как это делал клиент в первом варианте; получив ответ, он передает его клиенту, который все это время просто ждал его от своего локального DNS-сервера.

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

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

5. URI-URL-URN

URI Uniform Resource Identifier (унифицированный идентификатор ресурса) [5].

URL Uniform Resource Locator (унифицированный указатель местонахождения ресурса).

URN Unifrorm Resource Name (унифицированное имя ресурса). URI: обозначает имя и адрес ресурса в сети. Как правило делится на

URL и URN, поэтому URL и URN это составляющие URI.

URL: адрес некоторого ресурса в сети (доменное имя или IP-адрес), который определяет его местонахождение, и способ обращения к нему (протокол).

URN: имя некоторого конкретного ресурса в сети, который может находиться во множестве разных мест.

Итак, можно считать, что:

URI = URL или URI = URN или URI = URL + URN

Нет ничего лучше, чем конкретный пример: URI = http://handynotes.ru/2009/09/uri-url-urn.html URL = http://handynotes.ru

URN = /2009/09/uri-url-urn.html

30

6. ГРУППОВАЯ РАССЫЛКА В ИНТЕРНЕТЕ И ГРУППЫ РАССЫЛКИ

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

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

Групповая рассылка на прикладном уровне. Во втором методе также используется выборочная рассылка, но в дублирование и продвижение данных вовлекаются получатели. В данном случае отправитель рассылает копии только нескольким (или одному) из них, а затем сами получатели создают копии и переправляют их другим. Последние также могут создать копии и разослать их дополнительным получателям и т. д. Для реализации данной схемы необходимо создать и поддерживать инфраструктуру распределения на прикладном уровне. Как показано на рис. 4, б, единственная дейтаграмма методом выборочной рассылки посылается отправителем получателю, который делает две копии и посылает их остальным двум получателям тем же методом.

Явная групповая рассылка. Третья возможность заключается в предоставлении явной поддержки групповой рассылки на сетевом уровне. При таком подходе источник отправляет всего одну дейтаграмму. Эта дейтаграмма (или ее копия) дублируется маршрутизатором, и копии отправляются по нужным исходящим линиям. Данный подход иллюстрирует рис. 4, в, на котором маршрутизаторы, поддерживающие групповую рассылку, показаны темными. Здесь отправитель передает всего одну дейтаграмму, которая затем дублируется маршрутизатором. Одну из копий маршрутизатор посылает самому верхнему получателю, а вторая направляется правому маршрутизатору, который может посылать ее по своей локальной