Основы сетевого взаимодействия
Перед написанием сетевых приложений разберемся с некоторыми базовыми понятиями. Во-первых, определимся: что же такое сеть? В этой статье под сетью будем понимать совокупность компьютеров, объединенных таким образом, что они способны взаимодействовать между собой посредством сетевых протоколов с целью обмена данными.
Данные передаются по сети в виде небольших сообщений, называемых пакетами. Каждый из них содержит заголовок с адресом назначения, который используют сетевые устройства (например, маршрутизаторы и коммутаторы) для последующего перенаправления пакета.
Что такое сетевой протокол?
Сетевой протокол – это свод правил и стандартов для описания взаимодействия двух и более устройств сети. Поддержка протоколов закладывается на аппаратном и/или программном уровнях.
Сетевые протоколы описывают взаимодействие на различных уровнях: физическом (радиочастоты, сигналы), сетевом (маршрутизация пакетов, логическая адресация) и других. Уровни объединяют в сетевые модели или стеки протоколов. В основе работы интернета лежит стек TCP/IP, описывающий взаимодействие устройств в глобальной сети. Он состоит из двух протоколов – TCP и IP, первый из которых работает поверх второго.
Что такое CP (Transmission Control Protocol)?
TCP (Transmission Control Protocol) — это протокол управления передачей, который обеспечивает доставку и сборку данных в заданном порядке. TCP гарантирует целостность и упорядоченность данных, однако из-за дополнительных проверок его скорость может быть ниже по сравнению с другими протоколами.
Работу TCP можно разделить на три этапа:
- Установка сеанса связи с помощью так называемого трехстороннего рукопожатия.
- Разбиение данных на сегменты, их нумерация и отправка получателю.
- Завершение соединения путем обмена флагами FIN и ACK.
Что такое IP (Internet Protocol)?
IP (Internet Protocol) — это межсетевой протокол, отвечающий за адресацию: доставку определенных данных до целевого компьютера. Именно IP логически объединил локальные компьютерные сети в глобальную, больше известную как Интернет.
Таким образом, протокол IP отвечает за передачу данных, а TCP – за гарантию их доставки.
Стек TCP/IP состоит из четырех уровней:
Название уровня | Описание | Примеры протоколов |
Прикладной | Обеспечивает работу сетевых приложений | HTTP, DNS, FTP, SMTP |
Транспортный | Контролирует доставку сообщений и гарантирует корректную последовательность прихода данных | TCP, UDP, RSVP |
Межсетевой | Отвечает за взаимодействие между отдельными сетями, соединяет локальные сети с глобальной | IPv4, IPv6, ICMP |
Канальный | Отвечает за физический процесс передачи информации, её кодирование, разделение на пакеты и отправку по каналам | Ethernet, MAC, WLAN, Wi-Fi |
После прохождения транспортного уровня пакет попадает в управление операционной системы (ОС), которая подбирает подходящее сетевое приложение с помощью комбинации IP-адреса и сетевого порта.
Что такое IP-адрес?
IP-адрес – это уникальный адрес, идентифицирующий устройство в глобальной или локальной сети. Он представляется 32 или 128-битным числом для версий IPv4 и IPv6 соответственно.
Что такое сетевой порт?
Сетевой порт – это числовой идентификатор, который включается в заголовки транспортного уровня и используется для определения получателя пакета в пределах хоста. В заголовках протоколов TCP и UDP (о нем мы поговорим далее) порты хранятся в виде полей размером 16 бит и разделены на три диапазона: общеизвестные (0–1023), пользовательские (1024–49151) и частные (49152–65535).
Комбинация из IP-адреса и порта называется сокетом. Он представляет собой программный интерфейс для создания каналов взаимодействия между устройствами с целью обмена информацией. Сокеты используются во многих сетевых приложениях: веб-серверах, чатах, электронной почте и других.
Можно сказать, что сокет – это канал общения между программистом и ОС. Вместо того, чтобы разбираться в тонкостях работы протоколов, IP-адресов и портов, программисту достаточно создать в программе объект сокета для отправки и получения сообщений. При этом все задачи по передаче данных возлагаются на ОС.
В следующей части статьи изучим сетевое взаимодействие в Go и реализуем два вида сокетов: TCP и UDP. Второй из них основан на еще одном важном протоколе Интернета – UDP (User Datagram Protocol). Он обеспечивает передачу данных без необходимости установки сеансов связи и получения подтверждений, поэтому работает быстрее TCP, но не гарантирует целостность и упорядоченность информации. Из-за этой особенности UDP применяется там, где скорость работы важнее, чем потеря части пакетов, например, в стриминговых сервисах, онлайн-играх и голосовой связи.
Сетевое взаимодействие в Go
Перейдем к реализации сетевого взаимодействия средствами языка Go. Мы будем работать с клиент-серверной моделью, состоящей из клиента и сервера и работающей по следующим принципам:
- Клиент отправляет запрос на определенный сетевой порт и получает от него ответ.
- Сервер привязывает сетевые службы к портам, ожидает запросы от клиента и отсылает ему ответы.
Основным пакетом для сетевого программирования в Go является net. Он предоставляет интерфейсы сетевого ввода / вывода, разрешения доменных имен, работы с сокетами, протоколами TCP, IP и UDP.
Пакет net предоставляет доступ к низкоуровневым сетевым инструментам, но для большинства задач хватает нескольких базовых примитивов: функций Dial, Listen, Accept и интерфейсов Conn и Listener, включая их вариации для протоколов TCP, UDP и IP.
Детально рассмотрим устройство интерфейсов Conn и Listener, так как они содержат часто используемые методы для работы с соединениями. В листингах приведено лишь короткое описание методов, более подробную информацию о них можно найти в документации пакета net.
Интерфейс Conn:
Можно заметить, что интерфейс net.Conn реализует интерфейсы io.Reader и io.Writer, поэтому обладает совместимостью со многими объектами пакетов io и bufio. Эта особенность упрощает реализацию ввода-вывода в сетевых соединениях и открывает возможность настройки буферизации и десериализации данных. Для полноценного изучения пакетов io и bufio рекомендуем обратиться к статье: Самоучитель по Go для начинающих. Часть 14. Интерфейсы ввода-вывода. Буферизация. Работа с файлами. Пакеты io, bufio, os.
Интерфейс Listener:
Для принятия входящих соединений используются функции Dial и Listen, возвращающие типы Conn и Listener соответственно:
Параметры network и address задействованы во многих объектах пакета net, поэтому разберем их детальнее:
- параметр
network
может принимать значения"tcp"
,"tcp4"
(для IPv4),"tcp6"
(для IPv6), аналогичные названия для UDP и IP, а также"unix"
,"unixgram"
и"unixpacket"
. - параметр
address
для протоколов TCP и UDP должен иметь вид"хост:порт"
, для IP –"хост"
. Если значение хоста пусто, например, имеет вид":80"
или"::"
, то будет использован локальный хост (localhost).
Самое время применить на практике теоретические знания об устройстве сетей и основных компонентов пакета net. Напишем несложный код для отправки HTTP-запроса по протоколу TCP с использованием функции Dial
:
Обратите внимание: после открытия соединения необходимо обязательно предусмотреть, как оно будет закрыто. Чаще всего для отложенного закрытия используется конструкция defer conn.Close()
.
В результате выполнения кода в консоль будет выведен стандартный HTTP-ответ от сервера, содержащий справочную информацию:
TCP-сервер
Рассмотрим реализацию TCP-сервера, который открывает сетевой порт на прослушивание, принимает соединения от клиента и обрабатывает его запросы в отдельной горутине. Чтобы сократить код и сконцентрироваться на структуре TCP-сервера, опустим обработку ошибок, оставив написание этого функционала в качестве полезного упражнения:
TCP-клиент
Теперь приведем код TCP-клиента, который считывает из стандартного потока ввода сообщение, отправляет его серверу и получает от него ответ:
Для тестирования кода TCP-клиента сначала следует в отдельном окне запустить TCP-сервер на открытом сетевом порту. Примерный вариант взаимодействия между клиентом и сервером может выглядеть так:
Вывод результата выполнения кода TCP-клиента:
UDP-сервер
Основное отличие UDP-сервера от TCP-сервера заключается в том, что первый из них не устанавливает отдельного соединения с клиентом, а просто прослушивает определенный порт и обрабатывает входящие запросы по мере их поступления. Поэтому функция net.ListenUDP
возвращает указатель на тип UDPConn, в то время как функция net.ListenTCP
– указатель на тип TCPListener
, что избавляет UDP-сервер от необходимости использовать метод Accept
для принятия соединений:
UDP-клиент
Коды TCP- и UDP-клиентов практически не отличаются, за исключением того, что для чтения данных из UDP-соединения используется отдельный буфер и метод ReadFromUDP
:
Заключение
В этой части самоучителя мы познакомились с основами компьютерных сетей: изучили основные протоколы, на которых функционирует Интернет, а также узнали о сетевых моделях, стеках, портах и сокетах. Затем мы рассмотрели принципы сетевого программирования в Go и устройство пакета net, после чего закрепили знания на практических примерах.
В следующей части самоучителя познакомимся с еще одним важным протоколом Интернета – HTTP, который лежит в основе обмена данными. Детально рассмотрим пакет net/http и с помощью его компонентов реализуем клиент-серверное взаимодействие по протоколу HTTP.
Содержание самоучителя
- Особенности и сфера применения Go, установка, настройка
- Ресурсы для изучения Go с нуля
- Организация кода. Пакеты, импорты, модули. Ввод-вывод текста.
- Переменные. Типы данных и их преобразования. Основные операторы
- Условные конструкции if-else и switch-case. Цикл for. Вложенные и бесконечные циклы
- Функции и аргументы. Области видимости. Рекурсия. Defer
- Массивы и слайсы. Append и сopy. Пакет slices
- Строки, руны, байты. Пакет strings. Хеш-таблица (map)
- Структуры и методы. Интерфейсы. Указатели. Основы ООП
- Наследование, абстракция, полиморфизм, инкапсуляция
- Обработка ошибок. Паника. Восстановление. Логирование
- Обобщенное программирование. Дженерики
- Работа с датой и временем. Пакет time
- Интерфейсы ввода-вывода. Буферизация. Работа с файлами. Пакеты io, bufio, os
- Конкурентность. Горутины. Каналы
- Тестирование кода и его виды. Table-driven подход. Параллельные тесты
- Основы сетевого программирования. Стек TCP/IP. Сокеты. Пакет net
Комментарии