Ликбез по программированию. Сети и сетевые протоколы

Компьютер — это инструмент, которым нужно уметь пользоваться. Не секрет, что современное коммерческое программирование отличается от теоретического, и приложением «Hello, World!» вы никого не удивите — существуют потребности иного толка и другого уровня. В новообразованную рубрику (или цикл статей) пишут не только студенты, но и просто люди, которые хотят научиться реально программировать. Часть из них хочет воплотить в жизнь какие-нибудь планы, другая — приобрести дополнительную профессию. Приступим…

Достаточно много вопросов задается по сетям, протоколам... Конечно, часто вообще стесняются показать незнание и спросить. А прочитать ликбез в газете доступно каждому:). Постараемся объяснить все на максимально понятном уровне. Конечно, по сетям написано n-e количество полезных и объемных книг, но наш материал для многих может стать просто хорошей точкой входа в тему. Мы не претендуем на лавры «полного подробного руководства».

Также мы не станем заниматься попытками объять необъятное, а обратимся к письму Андрея из Минска, который сетовал на то, что локальные приложения он может программировать легко, но когда речь «заходит об Интернете»… :) Само письмо приводить не будем, отмечу только, что сети — это дополнительный элемент в современном программировании, не более того. То есть работа с ними ничего особенно сложного не представляет. Изначально стоит сказать, что протоколов — море, но при этом существуют стандартные взаимосвязанные цепочки, и выбрав, например, вариант HTTP (FTP, Gopher и т.п.) —TCP—IP, мы подразумеваем не так много технологий.
Просто очень часто начинающих отпугивает именно количество аббревиатур.

Пример из жизни

Давайте немного расслабимся и опишем обыкновенную ситуацию в виде сценки.
Представьте себе офис какой-либо фирмы, занимающейся, например, продажей строительного оборудования. У нее есть своя мини-АТС, которая объединяет работников компании, при этом есть и общие (городские) номера, по которым звонят извне.
Вы — заказчик, ищете бетономешалку. Общение происходит так:
Набираете номер. Соединение успешно.

Диспетчер: «Фирма «Все для планеты». Здравствуйте!».
Вы: «Здравствуйте, мне нужно получить информацию по бетономешалкам».
Диспетчер: «Сейчас переключу…». Переключает на внутренний телефон 249.

Секретарь отдела: «Здравствуйте. Отдел сбыта строительной техники. Я вас слушаю».
Вы: «Здравствуйте. Мне нужно получить техническую спецификацию и прайсы на такую-то модель бетономешалки».
Секретарь отдела: «Вы от фирмы или частное лицо?».
Вы: «Я представитель фирмы N».
Секретарь отдела: «Минуточку… Переключаю».

Менеджер Николай: «Здравствуйте, чем могу помочь?».
Вы: «Мне нужно получить техническую спецификацию и прайсы на такую-то модель бетономешалки».
Менеджер Николай: «Хорошо, вам удобнее по e-mail или факсом?»
Ну и причем здесь пример? Прочитайте следующее:
1. Введите IP… (в нашем примере это городской номер телефона). По IP-адресу пакет доставляется до конкретного компьютера.
2. Введите порт… (в нашем примере переключение на внутренний номер отдела). По номеру порта определяется, для какой именно программы предназначается пришедший пакет. Если бы у фирмы в нашей сценке не было отдела строительной техники, то вы бы обратились, что называется, «не по адресу».
3. Введите имя… пароль… (в нашем примере вопрос о том, кто вы).
4. Проверка прав доступа, предоставление доступа к определенной папке/сервису (в нашем примере — к менеджеру).
5. Запрос на получение данных.
6. Обмен данными.

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

На этом примере без всяких схем и графиков можно вывести правило:
Если вам что-то нужно от кого-то, то вы — клиент, если кому-то что-то нужно от вас, то вы — сервер.

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

Теперь перейдем к техническим деталям.

Семь или четыре? Сначала семь!

Изначально в основу теории (как, собственно, и практики) сетей и сетевых протоколов была положена модель OSI (Open Systems Interconnection), разработанная известной всем Международной организацией по стандартам ISO. Что такое модели ISO как таковые? В любых сферах — это описания технологических стандартов, на базе которых (или под которые) реализуются определенные технологии. Модели ISO справочные и носят
рекомендательный характер. Что касается конкретно сетевых взаимодействий, то в рамках OSI мы имеем семь уровней, от аппаратного (физического) до прикладного (сервисы).

Перечисляем (OSI):
1. Physical layer. Физический уровень (кабели, сетевая карта).
2. Data-link layer. Канальный уровень (передача данных между любыми узлами в сетях).
3. Network layer. Сетевой уровень (доставка пакета любому узлу в сетях).
4. Transport layer. Транспортный уровень (средства для установления соединения, буферизации, нумерации и упорядочивания пакетов).
5. Session layer. Уровень сеанса (управление диалогом между узлами).
6. Presentation layer. Уровень представления (преобразование данных, например, сжатие или шифрование).
7. Application layer. Прикладной уровень (сервисы).

Изначально новичкам это может показаться сложным. На самом деле, это не так, если разбирать все по косточкам и… как минимум знать направление движения по пунктам. Итак, при передаче данных с использованием HTTP, FTP или E-mail-сервисов, вы стартуете с седьмого уровня и поэтапно двигаетесь к первому. Другая машина, получив пакет, начинает с физического уровня и двигается к седьмому. Обратите внимание на слово «сервисы» в 7 пункте, это уровень общения приложение ->сервис. Ведь по существу, можно добавить и восьмой пункт — пользователь->приложение. О нем не говорится явно, но это нужно понимать.

Итак, основное правило:
. Передача данных: 7 -> 1.
. Получение данных: 1-> 7.

В данном случае мы не используем понятия низкого и высокого уровней, чтобы вы не запутались, хотя в документациях и учебных материалах, основанных на OSI, часто под высоким подразумевают физический, а под низким — прикладной (дело в нумерации списка). А запутаться вы можете просто, поскольку в программировании аппаратный уровень всегда считается низким. Правильно же под верхним уровнем подразумевать программную часть (в нашем случае 5-7).

В общем, семь пунктов. Как это реализуется технически? Допустим, мы передаем(!) данные. На прикладном уровне к пакету добавляется(!) заголовок, потом осуществляется переход к уровню представления, где к нему опять же добавляется собственный заголовок. На уровне сеанса пакет получает еще один заголовок и так далее, пока все не доходит до физического уровня.

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

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

О пакетах…

Пакет содержит информацию о себе и данные, которые вы хотите передать. При прохождении цепочки 7-> 1 (передача) он обрастает служебными данными, а при 1->7 (получение) эти данные удаляются теми, кому они предназначены.

Конкретный пример семи пунктов OSI

Давайте представим модель на базе конкретного примера, причем для более близкого сопоставления со структурой OSI (соответствия с семью пунктами), возьмем вариант NetBIOS на прикладном уровне. На самом деле это не так важно, ведь нам нужно понять основную структуру.

Все аббревиатуры будут расшифрованы. Итак, наши семь пунктов.
1. Физический уровень. Сетевая карта. Трансляция пакета данных.
2. Канальный уровень. Драйвер сетевой карты. NDIS. PPP/SLIP.
3. Уровень сети. IP, ARP, RARP.
4. Уровень транспорта. TCP.
5. Уровень сеанса. Интерфейс TDI.
6. Уровень представления. NetBIOS на основе TCP/IP.
7. Прикладной уровень. NetBIOS.

Теперь по порядку. С аппаратными уровнями структурно все более-менее понятно, но поскольку мы решили все расшифровывать, стоит остановиться на втором пункте.

Пункт 2. Для передачи пакетов необходимо знать аппаратный адрес получателя, или, как принято называть — MAC-адрес. Он является уникальным и прошивается в сетевом устройстве на заводе-изготовителе. То есть, другими словами, в качестве адресов на канальном уровне используются МАС- адреса устройств. Чтобы было совсем понятно, проведем параллель с мобильной связью. У вас есть свой номер, но у каждого телефона имеется и отдельный номер, данный изготовителем. Примерно так.

NDIS (Network Driver Interface Specification) — поддержка передачи данных на аппаратном уровне. Причем речь идет обо всех возможных сетевых взаимодействиях. Например, говоря «сети», мы сейчас больше подразумеваем Интернет, но коммуникации между компьютерами могут быть различными, с использованием разных технологий и устройств (Ethernet, IR, serial port). Это достаточно сложная тема для ознакомительной статьи. Подробности вы можете узнать после.

PPP (Point-to-point protocol) — коммуникационный протокол для подключения компьютера к сети. Речь идет о конкретной поддержке физического подключения, и как самый яркий пример, вы используете PPP для соединения с Интернетом. PPP подразумевает свое семейство промежуточных протоколов, благодаря которым и происходит подключение. В более старой литературе в качестве альтернативы PPP вы можете встретить протокол SLIP.

Пункт 3. IP (Internet Protocol) находится на сетевом уровне и отвечает за передачу данных. По протоколу IP пакеты просто отправляются в сеть без ожидания подтверждения о получении данных (АСК Acknowledgment). В свою очередь, пакет данных включает адреса отправителя и получателя, идентификатор протокола, TTL (время жизни пакета) и контрольную сумму для проверки целостности пакета. Здесь есть одно «но», которое многие уже могли заметить. Отправитель не может проследить не только целостность пакетов (это может узнать только получатель), но и саму гарантию доставки пакетов. Эту проблему решают другие протоколы.

На данном уровне производится переход от MAC-адресов к IP-адресам и обратно. Протокол ARP (Address Resolution Protocol, протокол определения адреса) предназначен для определения аппаратного (MAC) адреса компьютера в сети по его IP-адресу. RARP (Revers Address Resolution Protocol) работает обратно.
IP-адрес — уникальный 32-битный адрес, назначенный каждому узлу Интернета.

Пункт 4. TCP (Transmission Control Protocol) — один из основных транспортных протоколов. Он напрямую взаимодействует с IP, вернее, предоставляет в его пользование (или получает от него) TCP-пакеты. Объяснить принцип действия транспортных протоколов можно и просто. Вам нужно отправить данные, если их порция большая и не вмещается в один пакет, то они разбиваются на несколько TCP-пакетов. Сами TCP-пакеты не содержат адресов отравителя/получателя, поскольку оные присваиваются на уровне IP. То есть, «голый» TCP-пакет вы отправить не можете, потому как неизвестно кому. При этом именно TCP устраняет недостатки IP в области проверки целостности и гарантии доставки. Данный транспортный протокол организует определенную связь между отправителем и получателем, он работает по технологии "клиент-сервер".

Архитектура TCP/IP, которую вы можете найти в справке по Visual Studio (для Windows CE)


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

Пункт 5. Уровень сеанса подразумевает управление диалогом между узлами, в его рамках обеспечивается возможность фиксации активной на данный момент стороны. TDI (Transport Driver Interface) является, как бы это сказать проще, верхним уровнем NDIS. Например, NDIS подразумевает поддержку выполнения транспортировки на нижнем (аппаратном) уровне по стандартному протоколу, такому как TCP/IP, в то время как TDI отвечает за более высокий уровень. Здесь вы можете запутаться, впрочем, и информация на данный момент для вас не будет особенно актуальной.

Пункты 6 и 7. NetBIOS (Network Basic Input Output System) является набором API-функций для работы с сетью. Он работает только на программном уровне и отвечает за формирование пакетов для отправки данных, причем в большинстве случаев физически они могут передаваться либо по TCP/IP, либо по IPX/SPX (другие стандарты для сетей Novell).

Семь или четыре? Можно и четыре…

Microsoft очень часто ругают, хотя у каждой медали есть две стороны. Например, лично мне нравится, когда производятся разумные упрощения. Помните, мы говорили о том, что пункты 1-3 — аппаратные, 4 — промежуточный, 5-7 — программный? Так вот, Microsoft пошла на упрощения, фактически заменив семь пунктов на четыре, объединив все под технологией MS TCP/IP:
1. Аппаратный уровень. Пункты 1 и 2 OSI.
2. Межсетевой уровень. IP.
3. Уровень транспорта. TCP или UDP.
4. Уровень приложения. Сокеты Windows.

На самом деле, это условное разбиение, которое вы можете увидеть в некоторых книгах. Если же вы обратитесь к справке Visual Studio с запросом «TCP/IP Architectural Model», то получите 7 пунктов OSI и распределение между ними протоколов и связей (там показан пример для Windows CE). Присмотревшись, обнаружите, что упрощение возникло в силу того, что в рамках Microsoft один пункт может объединять несколько OSI.

Что такое сокеты?

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

Вы можете одновременно открыть несколько сокетов, и ничто не ограничивает максимальное число открытых сокетов.

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

Сравнение MS TCP/IP и OSI (взято из книги М. Е. Фленова «Программирование на C++ глазами хакера»)


TCP или UDP?

Для проверки гарантированной доставки данных протокол TCP организует определенную связь отправителя с получателем (клиента с сервером). Происходит обмен данными, благодаря которому получатель знает количество пакетов, которые он должен принять, их очередность и так далее. Если пакет не получен, протокол посылает его заново. На самом деле, механизм общения достаточно прост, но именно из-за гарантированного качества доставки TCP/IP работает достаточно медленно.

UDP (User Datagram Protocol) объясним с помощью нескольких определений: (а) — это облегченный TCP, (б) — это TCP без проверки качества доставки, (в) — это протокол, работающий без установления связи, как говорят, просто «выбрасывающий данные в сеть». Никакой проверки качества доставки нет, если один пакет потерялся в дороге, то он и исчезает. Мало того, если говорить образно, вы посылаете: «Привет, меня зовут Сергей», а получатель может принять строку в виде: «привет, Сергей меня зовут». Но UDP быстр. Он часто используется для обеспечения живого общения (чатов), трансляций (интернет-радио). Ведь, по существу, если один пакет потеряется в пути, то вы услышите щелчок в музыкальной композиции, не более того.

Сервисы

К сервисам или сервисным протоколам относятся FTP, HTTP и так далее. Они позволяют взаимодействовать по определенным правилам на уровне пользовательских интерфейсов и приложений. Сервисы могут базироваться как на TCP, так и на UDP.

Помимо этого, сервисы вы можете писать и сами.

Программирование

Итак, в рамках Visual Studio программирование сокетов, создание клиентских и серверных программ проще всего начать с использования класса CSocket. Он является наследником СAsyncSocket, причем работая с ним, вы по умолчанию используете TCP/IP.

После этого имеет смысл начать программировать с библиотекой Winsock или Winsock2. На этой базе вы сможете запрограммировать все, что угодно:). Также есть и библиотеки afxinet и wininet. Например, в рамках программирования сервисов, например, написания HTTP клиентов и серверов, FTP клиентов можно использовать конкретный класс CInternetConnection.

Программирование с сокетами, создание клиент-серверных связей, TCP/IP, UDP, организация передачи данных большого объема, синхронный и асинхронный режимы просто превосходно показаны в книге М. Е. Фленова «Программирование на C++ глазами хакера». Насколько мне известно, подобная есть и для Delphi (автор равно хорошо владеет двумя языками/средами). Если вам сложно освоить эти вопросы (а я видел некоторые учебные методические пособия:)))) и книги), то Фленов вам поможет. Чуть хуже все описано в справке Visual Studio.

В играх вместо сокетов раньше зачастую использовали более высокоуровневую модель — DirectPlay. DirectPlay представляет собой надстройку над сокетами, предоставляющую набор высокоуровневых функций (а, казалось бы, куда уже выше сокетов?). И хотя в старых книгах об этом говорится, на сегодня тема DirectPlay не актуальна.

Тестовое задание дано в приложении к статье.

Приложение к «Ликбез по программированию. Сети и сетевые протоколы»

В качестве практикума по программированию сокетов я составил задание, показанное на рисунке. Оно спроектировано так, чтобы, выполнив его, вы смогли сказать: «Я уже многое знаю! И во многом разбираюсь». Условно назовем эту программу «Сетевой хамелеон».

За основу возьмите Winsock2. В качестве настольного руководства рекомендуется использование книги М.Е. Фленова «Программирование на C++ глазами хакера», а также открытые коды из Интернета. Правда, если вы будете все выполнять под Visual C++ образца MSVS 2008, да и, в принципе, вообще, то для организации беспроблемной работы, связанной с подключениями и обменом данными, разберитесь с использованием потоков. Возможно, а это вероятнее всего, вы предусмотрите другую организацию процессов, чем у Фленова и в некоторых примерах открытых кодов.

Интерфейс включает кнопки 1 и 2 выбора режима приложения (клиент/сервер), рядом с каждой из них есть окна 3 и 4 (EditBox), в которое вы должны ввести номер порта. Для режима клиента вы указываете номер порта сервера, к которому хотите подключиться, для режима сервера — номер порта, на котором он запустится.

Тестировать мы все будем на одной и той же машине (компьютере), запустив сразу несколько идентичных приложений.
Стоит сказать, что порты 0—1023 зарезервированы для стандартных служб, поэтому их использование не рекомендуется, лучше выбирать что-нибудь в диапазоне 1024 — 65535.

Поскольку мы будем запускать все приложения на одном локальном компьютере, то укажите в коде IP-адрес: «127.0.0.1».

Кнопка подключения 5 активизирует режим программы. Если это сервер, то сообщение должно появиться в его логе 8 (ListBox). Если клиент, то сообщение должно появиться в окне лога на сервере, тот в свою очередь присылает подтверждение, которое отображается в логе клиента. Для сообщений предусмотрено окно ввода текста 6 (EditBox) и кнопка отправки 7.

Требования:
. В качестве транспортного протокола используется TCP.
. На компьютере можно запустить несколько серверов с разными портами.
. К каждому серверу может подключаться определенное количество клиентов, сервер работает в асинхронном режиме. Если он отправляет сообщение, то его получают все клиенты данного сервера.
. При отключении сервера завершают работу все его клиенты (автоматически закрываются клиентские программы).
. Если один из клиентов послал сообщение, начинающееся с команды, например, destruct, сервер отключается.

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

Кристофер christopher@tut.by


Компьютерная газета. Статья была опубликована в номере 35 за 2009 год в рубрике программирование

©1997-2024 Компьютерная газета