что такое протокол в программировании
О протоколах передачи данных
В этой статье я хочу поделиться личным, не претендующим на академичность, опытом в работе с различными закрытыми протоколами передачи данными (в основном на прикладном-сеансовом уровнях).
Достаточно часто мне приходиться сопрягаться со специализированным ПО (и железом, хотя в конечном итоге идет сопряжение со вшитым на плату фирмвейром), изготовитель каждого из которых предоставляет свой протокол обмена данными.
Какими свойствами и особенностями обладает хороший, годный грамотный, качественный протокол?
В идеале, протокол должен быть абстрагирован от более нижнего уровня взаимодействия, будь то передача по TCP, UDP, по serial порту, USB, Bluetooth, через цифровой радиосигнал, или даже по голубиной почте. И надо учитывать, что далеко не все из них гарантируют доставку и\или достоверность передающихся данных.
Небольшой дисклеймер: говоря о достоверности данных, я имею ввиду их неискаженность вследствие помех и иных ошибок в среде передачи. В статье я не буду затрагивать темы пласта технологий, связанных с безопасностью в ИТ. Допустим что наши Алиса и Боб могут друг другу доверять, и никакая Ева им помешать не может. (Например у коллег вопрос безопасности решается включением всех территориально разделенных участников взаимодействия в хорошо защищенный VPN, не имеющий в свою очередь доступа наружу)
В большинстве протоколов реализована схема «Вопрос-Ответ». Это можно представить как разговор, в котором на каждую реплику своего собеседника вы реагируете вербально, и в том же смысловом ключе. Таким образом участниками взаимодействия достигается уверенность в том, что их сообщения переданы и адекватно восприняты. Однако эта схема допустима и эффективна не для всех задач: в случаях когда задержка в общении должна быть минимизирована, или ответ на каждую из многочисленных реплик признается избыточным (например для отладочных сообщений), реализуется схема «Старт-Стоп». При получении сообщения на «Старт» ваш собеседник начинает сыпать в вас потоком реплик, и замолкает лишь при слове «Стоп». Сообщения, отправляемые в потоке, обычно имеют инкрементируемый порядковый номер, и если при принятии потока сообщений были проблемы с обработкой\было пропущено одно из них, его можно перезапросить отдельно по этому самому номеру.
Все протоколы можно разделить на две группы, (по представлению данных): символьные и бинарные.
Символьные протоколы, с которыми мне приходилось встречаться, базировались либо на XML, либо на JSON-строках. Из их достоинств можно упомянуть о более простой отладке взаимодействия (вследствие их читаемости), о простоте реализации (наличия готовых парсеров), и пресловутой универсальности.
Теперь о недостатках. Очевидно, что такие протоколы являются крайне избыточными, мизерная доля полезной информации плавает в массивной, неэффективной обёртке. При передаче любой числовой информации приходиться заниматься их конвертацией в строковое представление и обратно. Больным местом является передача бинарных данных (и хорошо, что без них бывает можно обойтись, но в ряде случаев это невозможно). Составители протоколов обычно выкручиваются применением Base64, или даже просто передачей бинарной строки в её hex-овом представлении, по два символа на байт.
Также хочется отметить, что полная спецификация того же XML крайне обширна, и стандартные парсеры, при всей их полноте возможностей, достаточно громоздки и медлительны, поэтому распространена практика, когда отдел или контора в итоге пишет и пользуется собственным парсером.
Конечно, для определенных задач, символьные протоколы являются, если не наиболее эффективным, то по крайней мере вполне приемлимым вариантом, но мы с вами идём дальше.
Теперь бинарные протоколы. Сразу же надо вспомнить о Гулливерских войнах тупоконечников и остроконечников. Лично я симпатизирую big-endian, т.к. не считаю неявную типизацию little-endian «чем-то хорошим», да и в моей среде разработки big-endian является нативным.
Бинарные протоколы (не все, но те, которые я отношу к грамотным) можно разделить на два уровня: уровень контейнера и уровень данных. На плечи первого уровня ложится ответственность за целостность и достоверность передачи данных, а так же за доступность обнаружения сообщения в байтовом потоке, и, само собой, за хранение в себе сообщения уровня данных. Второй уровень должен содержать информацию, ради которой всё сетевое взаимодействие и затевалось, в удобном для обработки формате. Его структура в основном зависит от решаемых задач, но и по нему есть общие рекомендации (о которых ниже).
Размеры сообщений (дискретных пакетов байт, которые можно обрабатывать независимо от предыдущих и последующих принимаемых данных) бывают фиксированными и переменными. Понятно, что с фиксированным размером сообщений всё проще — вычитается, начиная с заголовка (о нём позже), определенное количество байт и отправляется на обработку. Зачастую, для обеспечения гибкости, составители таких протоколов включают в сообщение область фиксированного размера (иногда до 80% от общего объема), зарезервированное под модификации нынешнего протокола. На мой взгляд, это не самый эффективный путь обеспечения гибкости, зато избыточность появляется еще какая.
Рассмотрим сообщения переменной длины.
Тут уже можно подробней поговорить о непременном атрибуте бинарного сообщения в любом протоколе — о заголовке (Это вышеупомянутый уровень контейнера).
Обычно заголовки начинаются с константной части, позволяющей, с определенной вероятностью обнаружить начало сообщения в непрерывном байтовом потоке. Очевидно, что имеется риск появления такой константы в произвольном потоке байт, и, хотя увеличение объема этот риск снижает (я встречал константы вида 0123456789VASIA9876543210), целесообразней использовать проверки на основе подсчета контрольной суммы.
За константой обычно следует номер версии протокола, который дает нам понять, в каком формате должно происходить дальнейшее считывание (и имеем ли мы вообще возможность обработать это сообщение — вдруг такая версия нам неизвестна). Следующая важная часть заголовка: информация о самом содержимом контейнера. Указывается тип содержимого (по факту, тот же номер версии протокола для уровня данных), его длина и контрольная сумма. Имея эту информацию, можно уже без проблем и опасений считать содержимое и приступить к его разбору.
Но не прямо сразу! Заголовок должна заключать контрольная сумма его самого (исключая из расчета конечно саму контрольную сумму) — только так мы можем быть уверены в том, что считали только что не белиберду, а валидный заголовок, за которым следуют предназначенные нам данные. Не совпала контрольная сумма? Придётся искать следующее начало нового заголовка дальше по потоку…
Представим, что мы дошли до этапа, что получили наконец неискаженное сообщение уровня данных. Его структура зависит от той области задач той системы, в которой реализован ваш сетевой обмен, однако в общем виде у сообщения тоже бывает быть свой заголовочек, содержащий информацию о типе сообщения. Можно различить как общую специфику сообщения, (например «Запрос Set», «Утвердительный Ответ на Set», «Отрицательный Ответ на Set», «Запрос Get», «Ответ Get», «Потоковое сообщение»), так и конкретную область применение сообщения. Попробую привести пример с потолка:
Тип запроса: Запрос Set (0x01)
Идентификатор модуля-адресата сообщения: PowerSupplyModule (0x0A)
Идентификатор группы сообщений: UPS Management (0x02)
Идентификатор типа сообщения: Reboot (0x01)
Дальше тело сообщения может содержать информацию об адресе ИБП, который Модуль управления энергообеспечением должен перезагрузить, через сколько секунд это сделать и т.п.
На это сообщение мы рассчитываем получить ответное сообщение с типом запроса «Утвердительный Ответ» и последующими 0x0A0201 в заголовке.
Конечно, такое подробное описание типа сообщения может быть избыточным когда межсетевое взаимодействие не предусматривает большого числа команд, так что формировать структуру сообщения надо исходя из требований ТЗ.
Так же будет полезно, если сообщение с «Отрицательным Ответом» будет содержать код ошибки, из-за которой не удалось ответить на команду утвердительно.
Заканчивая своё повествование, добавлю, что тема взаимодействия приложений весьма обширна и порою холиворна(что по факту означает, что в ней нет технологии «серебряной пули»), и отмечу, что те взгляды, что я излагаю, являются лишь компиляцией из опыта по работе с отечественными и зарубежными коллегами. Спасибо за внимание!
upd.
Имел удовольствие пообщаться с критиком своей статьи, и теперь прихожу к осознанию, что я осветил вопрос со своей если можно так выразиться, «байтолюбской», точки зрения. Конечно, раз идет курс на универсальность обработки хранения и передачи данных, то в таком ключе символьные протоколы (в первую очередь говорю об XML) могут дать фору любым другим решениям. Но относительно попытки повсеместного их применения позволю себе процитировать Вирта:
Инструмент должен соответствовать задаче. Если инструмент не соответствует задаче, нужно придумать новый, который бы ей соответствовал, а не пытаться приспособить уже имеющийся.
Протоколы передачи данных: что это, какие бывают и в чём различия?
Авторизуйтесь
Протоколы передачи данных: что это, какие бывают и в чём различия?
Интернет очень большой и комплексный. Но на базовом уровне это всего лишь связь между различными компьютерами (не только персональными). Эта связь представляет из себя сетевые протоколы передачи данных — набор правил, который определяет порядок и особенности передачи информации для конкретных случаев.
Протоколов большое множество. Про основные из них рассказано далее.
IP — Internet Protocol
Протокол передачи, который первым объединил отдельные компьютеры в единую сеть. Самый примитивный в этом списке. Он является ненадёжным, т. е. не подтверждает доставку пакетов получателю и не контролирует целостность данных. По протоколу IP передача данных осуществляется без установки соединения.
Основная задача этого протокола — маршрутизация датаграмм, т. е. определение пути следования данных по узлам сети.
Популярная версия на текущий момент — IPv4 с 32-битными адресами. Это значит, что в интернете могут хранится 4.29 млрд адресов IPv4. Число большое, но не бесконечное. Поэтому существует версия IPv6, которая поможет решить проблему переполнения адресов, ведь уникальных IPv6 будет 2 ^ 128 адресов (число с 38 знаками).
TCP/IP — Transmission Control Protocol/Internet Protocol
Это стек протоколов TCP и IP. Первый обеспечивает и контролирует надёжную передачу данных и следит за её целостностью. Второй же отвечает за маршрутизацию для отправки данных. Протокол TCP часто используется более комплексными протоколами.
UDP — User Datagram Protocol
Протокол, обеспечивающий передачу данных без предварительного создания соединения между ними. Этот протокол является ненадёжным. В нём пакеты могут не только не дойти, но и прийти не по порядку или вовсе продублироваться.
Основное преимущество UDP протокола заключается в скорости доставки данных. Именно поэтому чувствительные к сетевым задержкам приложения часто используют этот тип передачи данных.
FTP — File Transfer Protocol
Протокол передачи файлов. Его использовали ещё в 1971 году — задолго до появления протокола IP. На текущий момент этим протоколом пользуются при удалённом доступе к хостингам. FTP является надёжным протоколом, поэтому гарантирует передачу данных.
Этот протокол работает по принципу клиент-серверной архитектуры. Пользователь проходит аутентификацию (хотя в отдельных случаях может подключаться анонимно) и получает доступ к файловой системе сервера.
Это не только система доменных имён (Domain Name System), но и протокол, без которого эта система не смогла бы работать. Он позволяет клиентским компьютерам запрашивать у DNS-сервера IP-адрес какого-либо сайта, а также помогает обмениваться базами данных между серверами DNS. В работе этого протокола также используются TCP и UDP.
HTTP — HyperText Transfer Protocol
Изначально протокол передачи HTML-документов. Сейчас же он используется для передачи произвольных данных в интернете. Он является протоколом клиент-серверного взаимодействия без сохранения промежуточного состояния. В роли клиента чаще всего выступает веб-браузер, хотя может быть и, например, поисковый робот. Для обмена информацией протокол HTTP в большинстве случаев использует TCP/IP.
HTTP имеет расширение HTTPS, которое поддерживает шифрование. Данные в нём передаются поверх криптографического протокола TLS.
NTP — Network Time Protocol
Не все протоколы передачи нужны для обмена классического вида информацией. NTP — протокол для синхронизации локальных часов устройства со временем в сети. Он использует алгоритм Марзулло. Благодаря нему протокол выбирает более точный источник времени. NTP работает поверх UDP — поэтому ему удаётся достигать большой скорости передачи данных. Протокол достаточно устойчив к изменениям задержек в сети.
Последняя версия NTPv4 способна достигать точности 10мс в интернете и до 0,2мс в локальных сетях.
SSH — Secure SHell
Протокол для удалённого управления операционной системой с использованием TCP. В SSH шифруется весь трафик, причём с возможностью выбора алгоритма шифрования. В основном это нужно для передачи паролей и другой важной информации.
Также SSH позволяет обрабатывать любые другие протоколы передачи. Это значит, что кроме удалённого управления компьютером, через протокол можно пропускать любые файлы или даже аудио/видео поток.
SSH часто применяется при работе с хостингами, когда клиент может удалённо подключиться к серверу и работать уже оттуда.
Протокол передачи данных
Из Википедии — свободной энциклопедии
Протокол передачи данных — набор определённых правил или соглашений интерфейса логического уровня, который определяет обмен данными между различными программами. Эти правила задают единообразный способ передачи сообщений и обработки ошибок.
Сигнальный протокол используется для управления соединением — например, установки, переадресации, разрыва связи. Примеры протоколов: RTSP, SIP. Для передачи данных используются такие протоколы как RTP.
Сетево́й протоко́л — набор правил и действий (очерёдности действий), позволяющий осуществлять соединение и обмен данными между двумя и более включёнными в сеть устройствами.
Разные протоколы зачастую описывают лишь разные стороны одного типа связи. Названия «протокол» и «стек протоколов» также указывают на программное обеспечение, которым реализуется протокол.
Новые протоколы для Интернета определяются IETF, а прочие протоколы — IEEE или ISO. ITU-T занимается телекоммуникационными протоколами и форматами.
Наиболее распространённой системой классификации сетевых протоколов является так называемая модель OSI, в соответствии с которой протоколы делятся на 7 уровней по своему назначению — от физического (формирование и распознавание электрических или других сигналов) до прикладного (интерфейс программирования приложений для передачи информации приложениями).
Сетевые протоколы предписывают правила работы компьютерам, которые подключены к сети. Они строятся по многоуровневому принципу. Протокол некоторого уровня определяет одно из технических правил связи. В настоящее время для сетевых протоколов используется сетевая модель OSI (Open System Interconnection — взаимодействие открытых систем, ВОС).
Модель OSI — 7-уровневая логическая модель работы сети. Реализуется группой протоколов и правил связи, организованных в несколько уровней:
Ликбез по программированию. Сети и сетевые протоколы
Компьютер — это инструмент, которым нужно уметь пользоваться. Не секрет, что современное коммерческое программирование отличается от теоретического, и приложением «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. Прикладной уровень (сервисы).
В данном случае мы не используем понятия низкого и высокого уровней, чтобы вы не запутались, хотя в документациях и учебных материалах, основанных на 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 организует определенную связь отправителя с получателем (клиента с сервером). Происходит обмен данными, благодаря которому получатель знает количество пакетов, которые он должен принять, их очередность и так далее. Если пакет не получен, протокол посылает его заново. На самом деле, механизм общения достаточно прост, но именно из-за гарантированного качества доставки 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, сервер отключается.
Нужно сказать, что выполнение задание займет много времени у начинающих, но вы приобретаете конкретные знания и опыт. А это — лучший приз!
Компьютерная газета. Статья была опубликована в номере 35 за 2009 год в рубрике программирование