ПЕРЕДАЧА ИНФОРМАЦИИ В СЕТЯХ
Введение в компьютерные коммуникации
Понятно, что тема передачи данных в цифровых сетях совершенно необъятна. Соответствующим частным и общим вопросам посвящено громадное количество литературы. Более того, отрасль сетевой транспортировки информации стремительно развивается, и при всем желании уследить за всеми последними достижениями здесь просто невозможно. По этой причине представляемый здесь материал совершенно не претендует на хоть малую степень полноты изложения, а всего лишь может рассматриваться как стартовая площадка для тех, кто намерен заниматься этой серьезной темой. Тем не менее, мы представим минимум сведений, которые позволят нам разрабатывать «действующие макеты» приложений, связанных с сетевыми технологиями.
Основой основ сетевых коммуникаций является понятие коммуникационных протоколов. В самом простейшем варианте под термином сетевой протокол следует понимать набор правил, по которым формируются пакеты (порции) данных для их дальнейшей передачи по компьютерным сетям. Протоколов создано великое множество, и, что самое поразительное, практически все это множество находит свое применение для решения тех или иных задач. Для того чтобы хоть как-то упорядочить все разработанные протоколы, принята специальная классификация, в основе которой лежат так называемые уровни. Заметим здесь, что таких уровней вычленили семь, и появился целый раздел информатики, называемый «семиуровневая иерархия сетевых протоколов». Для нас наибольший интерес будет представлять та часть иерархической структуры протоколов, корнем которой будет группа протоколов сетевого уровня. Сетевые протоколы ориентированы на конкретные виды сетей. Из всего этого семейства нам здесь понадобится наиболее популярный протокол, называемый просто IP — Internet Protocol. IP-протокол предназначен для работы в глобальных и локальных вычислительных сетях, в которых все узлы снабжены так называемыми IP-адресами. Назначение протокола сетевого уровня заключается только в обеспечении возможности передачи пакетов, то есть обеспечении маршрутизации данных. Сам по себе сетевой протокол не гарантирует доставку пакетов. Никакие функции контроля правильности передачи данных или исправления ошибок непосредственно на сетевой прото кол не возлагаются. Этим занимаются так называемые протоколы транспортного уровня.
Передаваемые по сети данные можно разделить на два типа: командные данные и информационные данные. К командной информации относятся сигналы вызова, разъединения, а также другие служебные сообщения. Информационные данные могут представлять собой текст, цифровой звук, цифровое изображение. Основное требование к передаче командной информации — отсутствие ошибок передачи. В результате необходимо использовать достоверный (надежный) протокол доставки сообщений. Обычно в качестве такого протокола используется протокол транспортного уровня TCP (Transport Control Protocol), обеспечивающий гарантированную доставку сообщений. Необходимо отчетливо представлять себе, что пакеты данных, путешествующие по сети, могут искажаться в результате сбоев в работе аппаратного обеспечения узлов или вообще теряться, например, из-за того, что время существования пакета может быть ограниченным. В этой связи во многих ситуациях (хотя и не всегда) контроль за правильностью прохождения пакетов оказывается совершенно необходимым. Именно этот контроль и выполняет протокол TCP. Не вдаваясь в детали, укажем только, что протокол имеет возможность получать из пункта назначения пакета информацию, подтверждающую правильность передачи данных. Если по истечении заданного времени соответствующее подтверждение не получено, производится повторная пересылка пакета. Так может продолжаться, в принципе, очень продолжительное время. Теперь, наверное, понятно, что при работе в Интернете, а иногда и в загруженной локальной сети, мы сталкиваемся с большими задержками при транспортировке данных. При передаче командной информации с этим приходится мириться. В то же время может возникать ситуация, когда гарантированная доставка информации не только не обязательна, но и нежелательна.
Ситуация, о которой мы говорим, имеет место, например, при передаче звука в реальном времени. Действительно, живой звук — человеческая речь, музыка, это объект, который нельзя «заморозить» во времени, по крайней мере, на сколько-нибудь продолжительное время. Оборванная на середине слова фраза в разговоре совершенно недопустима. (Считается, что максимально возможные задержки в речи не должны превышать величину 200—300 миллисекунд.) Запись цифрового звука осуществляется порциями. Совершенно очевидно, что и передача звуковой (и любой другой) информации производится порциями. В этой связи понятно, что если ошибки передачи пакетов не слишком частые, то лучше пожертвовать отдельным фрагментом речи длительностью, например, в десятую долю секунды, чем ждать, возможно, очень долго, пока этот фрагмент все же будет правильно передан. С передачей изображения ситуация менее жесткая. Изображение как раз и можно «заморозить» на экране. Хотя и здесь в некоторых случаях имеет смысл пропустить один или несколько кадров.
Теперь понятно, что для передачи мультимедиа реального времени протокол TCP не очень подходит. Необходимы инструменты негарантированной передачи информации, и такие инструменты имеются. В наших разработках мы будем применять протокол транспортного уровня UDP (User Datagram
Protocol — протокол передачи пользовательских дейтаграмм). Задачей этого инструмента является только отправка на заданный адрес порции данных любого типа — пользовательских дейтограмм. При этом факт неправильной пересылки информации фиксируется, но никакие действия при этом не предпринимаются. Очевидно, что для передачи служебных данных UDP не применим, но для передачи звука с возможными потерями фрагментов речи или музыки протокол оказывается очень полезным. При использовании UDP, помимо потерь отдельных блоков данных, может происходить нарушение очередности следования пакетов. Поскольку блоки информации могут следовать по различным маршрутам и на пути следования испытывать различные задержки, существует вероятность того, что пакет, отправленный позже предыдущего, достигнет адресата раньше. Для передачи звука такая ситуация крайне нежелательна. Хотя практика показала, что подобные нарушения очередности возникают достаточно редко, меры к их устранению все же принимаются. Одним из вариантов борьбы с этим явлением является использование джиттер-буфера временного хранения группы пришедших пакетов, где они упорядочиваются по времени отправки. Неизбежным при этом будет задержка, обусловленная накоплением пакетов, но это все же лучше, чем обмен местами, например, начала и конца слова или фразы. Другим способом устранения этой досадной помехи в современных профессиональных системах 1Р-телефонии является использование протокола RTP (Real Time Protocol) и его сателлита — протокола RTCP (Real Time Control Protocol). Протокол реального времени также является протоколом негарантированной доставки пакетов и также работает на основе сетевого IP. Говоря точнее, в отличие от UDP этот протокол выполняет гарантированную доставку только в течение заданного интервала времени. Если в этом интервале передать блок не удалось, то на этом обработка текущей порции данных заканчивается и начинает передаваться следующая. Таким образом, хотя и не обеспечивается доставка каждого из блоков, нарушений очередности не возникает и передача и прием пакетов строго распределены по равным временным интервалам.
Итак, мы имеем в своем распоряжении несколько наборов правил формирования пакетов данных, которые можем применять для тех или иных задач транспортировки информации. Работая с сетевым протоколом IP, мы имеем возможность адресовать передачу с помощью IP-адресов. В дальнейшем узел, которому предназначена транспортировка данных, будем называть удаленным хостом (remote host), а узел, являющийся источником информации, — локальным хостом (local host). Обычно пара из передающего и принимающего узлов называется парой КЛИЕНТ — СЕРВЕР, хотя такая классификация узлов довольно условна. Адреса узлов могут быть представлены четырехбайтовым числом, в котором десятичные представления байтов отделены друг от друга символом точка — обычное цифровое представление IP-адреса. Кроме того, хост может быть идентифицирован и символьным именем типа mail.ru. Символьное имя однозначно связано с цифровым адресом и назначается специальной службой сети. При программировании наших задач мы будем использовать исключительно цифровые IP-адреса. Здесь важно напомнить, что если компьютер не подключен к сети, но в операционную систему инсталлирован протокол IP, то машина имеет предопределенный адрес 127.0.0.1, который можно использовать, например, если вы создаете на своем компьютере одновременно и локальный и удаленный хосты. Для отладки разрабатываемых коммуникационных программ имеет смысл все тестировать «на себе» и только потом переходить к работе в сети.
Напомним также, что при подключении компьютера к сети ему присваивается реальный или внутрисетевой IP-адрес. При модемном подключении к провайдеру присваиваемый адрес будет меняться от сеанса к сеансу. Для того чтобы узнать свой текущий адрес в операционной системе Windows 98, можно запустить программу winipcfg, а в более поздних версиях ОС достаточно открыть свойства значка модема на панели задач. Можно также воспользоваться утилитой ipconfig.
Идентификация адресов хостов еще не достаточна для организации связи. Дело в том, что на машине может работать одновременно несколько коммуникационных процессов. Вы можете в одно и то же время скачивать из Интернета необходимый файл и работать, например, в Интернет-пейджере ICQ. Для того чтобы такая многозадачность могла работать и процессы не мешали бы друг другу, каждому приложению, занимающемуся приемом или передачей данных, сопоставляется так называемый порт. Не следует путать такой виртуальный порт с физическими последовательными и параллельными портами компьютера (СОМ и LPT), хотя и те и другие предназначены для обмена данными. Порт присваивается процессу в виде номера, представленного целым числом в достаточно широких пределах. Вообще говоря, номер порта может быть назначен процессу произвольно, но необходимо позаботиться о том, чтобы для двух или более запущенных на компьютере процессов порты не оказались одинаковыми. Следует, также, помнить, что существуют умолчания, в соответствии с которыми назначаются порты некоторых стандартных процессов. Так, например, порт 3128 назначается по умолчанию прокси-серверам, и занимать это значение другими процессами не рекомендуется. Здесь уместно сделать одно крайне важное замечание. На практике некоторые провайдеры ограничивают произвол в использовании номеров портов обычными пользователями — закрывают те или иные номера или диапазоны номеров. Делается это с целью обеспечения безопасности сетей, защиты от вирусов. По этой причине не исключена ситуация, когда разрабатываемое вами приложение отказывается работать в сети. Возможно, необходимо обратиться к провайдеру и узнать о возможности использования конкретного номера порта.
Теперь понятно, что всякий информационный процесс (процесс обмена данными между клиентом и сервером или двумя узлами) однозначно задается парой IP-адресов хостов и парой портов, назначенных приложениям на хостах. Совокупность адресов и портов процесса принято называть сокетом. Вообще говоря, понятие сокета в информатике более фундаментально, но точная формулировка автору неизвестна. Заметим только, что часто и не совсем верно под сокетом понимается постоянное соединение двух хостов, в отличие от соединения, создаваемого для «одноразовой» передачи данной порции информации.
Конкретные средства для передачи данных определяются средой разработки приложений. В используемой нами интегрированной оболочке Borland C++ Builder такие средства существуют и весьма разнообразны. На вкладке FastNet палитры визуальных компонентов собраны инструменты, позволяющие создавать коммуникационные приложения для широкого круга задач.
Компоненты NMMsg и NMMSGServ являются клиентским и серверными VCL, обеспечивающими передачу и прием текстовых сообщений между парой узлов. Обмен информацией производится по протоколу транспортного уровня TCP/IP. Для передачи данных произвольного типа (также по протоколу TCP/IP) целесообразно использовать так называемые потоки (Stream). В поток может быть помещена порция информации любого вида, и эта порция «переносится потоком» с одного компьютера на другой. Клиентская и серверная части потоков представлены компонентами NMStrm и NMStrmServ соответственно. Компонент NMUDP предназначен для передачи пользовательских дейтаграмм по протоколу UDP. Здесь разделение на серверную и клиентскую часть отсутствует. VCL наделена функциями как приема, так и передачи дейтаграмм.
На этой вкладке сосредоточены и многие другие коммуникационные визуальные компоненты. С их помощью можно создавать программы для работы с электронной почтой, FTP-системами, web-страницами и многое другое. Непосредственно к тематике наших изысканий эти инструменты отношения не имеют, однако для тех, кто заинтересуется указанными возможностями, мы можем порекомендовать отличную книгу (Козлова А. В. Программирование для Интернет в C++ Builder 5. — М.: БИНОМ, 2001).
С помощью визуальных компонентов Builder'a можно организовывать и сокетные соединения. Компоненты ClientSocket и ServerSocket, используемые для этих целей, находятся в палитре компонентов на вкладке Internet. К сожалению, в версиях Builder'a до шестой включительно не реализованы средства для работы с протоколом реального времени RTP. Тем не менее, уже включенных в пакет компонентов нам хватит для знакомства с программированием коммуникаций, к которому мы и переходим.