Введение
Сокеты – это способ обеспечения межпроцессного взаимодействия между программами, запущенными на сервере, или между программами, работающими на разных серверах. Обмен данными между серверами осуществляется с использованием сетевых сокетов, которые используют Протокол Интернета (IP) для инкапсуляции и обработки отправки и приема данных.
Сетевые сокеты как на клиенте, так и на сервере обозначаются своим сокетным адресом. Адрес представляет собой уникальное сочетание транспортного протокола, такого как Протокол Управления Передачей (TCP) или Протокол Пользовательских Датаграмм (UDP), IP-адреса и номера порта.
В этом руководстве вы узнаете о следующих различных типах сокетов, используемых для межпроцессного взаимодействия:
- Сокеты потоковой передачи, которые используют TCP в качестве транспортного протокола
- Сокеты дейтаграмм, которые используют UDP в качестве транспортного протокола
- Сокеты доменов Unix, которые используют локальные файлы для отправки и приема данных вместо сетевых интерфейсов и IP-пакетов.
В каждом разделе этого руководства вы также узнаете, как перечислить соответствующие типы сокетов в системе Linux. Вы будете изучать каждый тип сокета с использованием различных инструментов командной строки.
Предварительные требования
Примеры в этом руководстве были проверены на сервере Ubuntu 20.04. Вы можете следовать этому руководству, используя большинство современных дистрибутивов Linux на локальном компьютере или удаленном сервере, при условии, что у вас установлена эквивалентная версия каждого из необходимых инструментов для вашего дистрибутива.
Чтобы начать использовать Ubuntu 20.04, вам понадобится один сервер, который был настроен в соответствии с нашим Руководством по начальной настройке сервера для Ubuntu 20.04.
Вам также понадобятся несколько других пакетов, чтобы исследовать сокеты на вашей системе. Убедитесь, что кеш пакетов вашей системы обновлен с помощью команды apt update
:
Затем установите необходимые пакеты с помощью этой команды:
Пакет iproute2
содержит утилиту ss
, которую мы будем использовать для проверки сокетов. Мы будем использовать пакет netcat-openbsd
для установки netcat. Обратите внимание, что при вызове из командной строки netcat сокращается до nc
. Наконец, мы будем использовать пакет socat
, чтобы создать примеры сокетов.
Что такое сокет для потока данных?
Потоковые сокеты ориентированы на соединение, что означает, что пакеты, отправленные и полученные через сетевой сокет, доставляются операционной системой хоста для обработки приложением. Сетевые потоковые сокеты обычно используют протокол передачи данных (TCP) для инкапсуляции и передачи данных через сетевой интерфейс.
TCP разработан как надежный сетевой протокол, который основан на поддержании состояния соединения. Данные, отправленные программой с использованием потокового сокета на основе TCP, будут успешно получены удаленной системой (при отсутствии проблем с маршрутизацией, брандмауэрами или другими проблемами с подключением). Пакеты TCP могут приходить на физический сетевой интерфейс в любом порядке. В случае, если пакеты приходят в неправильном порядке, адаптер сети и операционная система хоста обеспечат их повторную сборку в правильной последовательности для обработки приложением.
A typical use for a TCP-based stream socket would be for a web server like Apache or Nginx handling HTTP requests on port 80
, or HTTPS on port 443
. For HTTP, a socket address would be similar to 203.0.113.1:80
, and for HTTPS it would be something like 203.0.113.1:443
.
Создание потоковых сокетов на основе TCP
В следующем примере вы будете использовать команду socat
(сокращение от SOcket CAT
) для эмуляции веб-сервера, прослушивающего HTTP-запросы на порту 8080 (альтернативный порт HTTP). Затем вы изучите сокет, используя команды ss
и nc
.
Сначала выполните следующие команды socat
, чтобы создать два потоковых сокета на основе TCP, ожидающих подключений на порту 8080
, с использованием интерфейсов IPv4 и IPv6:
- Аргументы
TCP4-LISTEN:8080
иTCP6-LISTEN:8080
– это тип протокола и номер порта для использования. Они указываютsocat
создать TCP-сокеты на порту8080
на всех интерфейсах IPv4 и IPv6, и прослушивать каждый сокет на наличие входящих соединений.socat
может прослушивать любой доступный порт на системе, поэтому любой порт от0
до65535
является допустимым параметром для опции сокета. - Опция
fork
используется для того, чтобы гарантировать, чтоsocat
продолжает работать после обработки соединения, в противном случае он автоматически завершится. - Путь
/dev/null
используется вместо удаленного сетевого адреса. В этом случае он указываетsocat
печатать входящие данные в файл/dev/null
, который молча отбрасывает их. - Флаг
ipv6only=1
используется для сокета IPv6, чтобы сообщить операционной системе, что сокет не настроен для отправки пакетов на адреса IPv4, отображенные в IPv6. Без этого флагаsocat
привяжется к адресам IPv4 и IPv6. - Символ
&
указывает оболочке запустить команду в фоновом режиме. Этот флаг гарантирует, чтоsocat
продолжит работу, пока вы вызываете другие команды для проверки сокета.
Вы получите вывод, подобный следующему, который указывает на два идентификатора процессов socat
, работающих в фоновом режиме вашей сеансе оболочки. Ваши идентификаторы процессов будут отличаться от выделенных здесь:
Output[1] 434223
[2] 434224
Теперь, когда у вас есть два процесса socat
, слушающих TCP-порт 8080
в фоновом режиме, вы можете изучить сокеты, используя утилиты ss
и nc
.
Изучение TCP-ориентированных потоковых сокетов
Чтобы изучить TCP-сокеты на современной системе Linux с помощью команды ss
, выполните ее с использованием следующих флагов для ограничения вывода:
- Флаги
-4
и-6
указываютss
проверять только IPv4 или IPv6 сокеты соответственно. Отсутствие этой опции будет отображать оба набора сокетов. - Флаг
t
ограничивает вывод TCP-сокетами. По умолчанию утилитаss
отображает все типы сокетов, используемых в системе Linux. - Флаг
l
ограничивает вывод прослушивающими сокетами. Без этого флага будут отображены все TCP-соединения, включая такие вещи, как SSH, клиенты, подключенные к веб-серверу, или соединения, которые ваша система может иметь с другими серверами. - Флаг
n
гарантирует отображение номеров портов вместо имен служб.
Сначала выполните команду ss -4 -tln
, чтобы изучить IPv4 TCP-ориентированные сокеты, слушающие соединения на вашей системе:
Вы получите вывод, подобный следующему:
OutputState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
LISTEN 0 1 0.0.0.0:8080 0.0.0.0:*
. . .
Могут быть и другие строки с другими портами в вашем выводе, в зависимости от того, какие службы запущены на вашей системе. Выделенная часть вывода 0.0.0.0:8080
указывает, что IPv4 TCP-сокет прослушивает все доступные интерфейсы IPv4 на порту 8080
. Служба, которая слушает только определенный IPv4-адрес, покажет только этот IP в выделенном поле, например 203.0.113.1:8080
.
Теперь выполните ту же команду ss
, но с флагом -6
:
Вы получите вывод, подобный следующему:
OutputState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
LISTEN 0 5 [::]:8080 [::]:*
. . .
Могут быть и другие строки с другими портами в вашем выводе, в зависимости от того, какие службы запущены на вашей системе. Выделенная часть вывода [::]:8080
указывает, что IPv6 TCP-сокет прослушивает все доступные интерфейсы IPv6 на порту 8080
(как указано символами ::
, которые представляют собой IPv6-нотацию для адреса, состоящего из всех нулей). Служба, которая слушает только определенный IPv6-адрес, покажет только этот IP в выделенном поле, например [2604:a880:400:d1::3d3:6001]:8080
.
Подключение к потоковым сокетам на основе TCP
До сих пор вы узнали, как создавать и перечислять TCP-сокеты как на интерфейсах IPv4, так и IPv6. Теперь, когда у вас есть два сокета, прослушивающих соединения, вы можете экспериментировать с подключением к сокетам с помощью утилиты netcat.
Использование netcat для тестирования TCP-соединений с локальными и удаленными сокетами – очень полезная техника поиска неисправностей, которая может помочь выявить проблемы с подключением и брандмауэрами между системами.
Чтобы подключиться к сокету IPv4 через локальный адрес обратной петли с использованием netcat, выполните следующую команду:
- Флаг
-4
сообщает netcat использовать IPv4. - Флаг
-v
используется для печати подробного вывода на ваш терминал. - Опция
-z
обеспечивает подключение netcat только к сокету, без отправки данных. - Используется локальный адрес обратной петли
127.0.0.1
, поскольку у вашей системы есть собственный уникальный IP-адрес. Если вы знаете IP-адрес вашей системы, вы можете также провести тестирование с его использованием. Например, если публичный или частный IP-адрес вашей системы – 203.0.113.1, вы можете использовать его вместо IP-адреса обратной петли.
Вы получите вывод, подобный следующему:
OutputConnection to 127.0.0.1 (127.0.0.1) 8080 port [tcp/http-alt] succeeded!
Выделенная строка – это вывод от netcat. Он указывает, что netcat подключился к TCP-сокету, прослушивающему адрес обратной петли 127.0.0.1
IPv4 на порту 8080
. Вторую строку можно игнорировать, она относится к процессу socat, запущенному на фоне в вашем терминале.
Теперь вы можете повторить тот же тест подключения, но с использованием IPv6. Выполните следующую команду netcat:
Вы должны получить вывод, аналогичный следующему:
OutputConnection to ::1 8080 port [tcp/http] succeeded!
Выделенная строка – это вывод от netcat. Он указывает, что netcat подключился к TCP-сокету, прослушивающему адрес обратной петли ::1
IPv6 на порту 8080
. Снова можно игнорировать вторую строку вывода.
Чтобы очистить ваши сокеты, вам нужно выполнить команду fg
(foreground) для каждого процесса socat, который вы создали. Затем вы будете использовать CTRL+C
, чтобы закрыть каждый socat. fg
приведет процессы на передний план вашего терминала в обратном порядке, в котором вы их запустили, так что при его выполнении второй экземпляр socat
будет тем, с которым вы взаимодействуете первым.
Запустите fg
, чтобы привести второй экземпляр IPv6 socat на передний план вашего терминала. Затем выполните CTRL+C
, чтобы закрыть его.
Вы получите вывод, подобный следующему:
Outputsocat TCP6-LISTEN:8080,ipv6only=1,fork /dev/null
Нажмите CTRL+C
, чтобы остановить процесс.
Теперь снова запустите fg
, чтобы очистить первый IPv4 сокет. У вас должен быть вывод, подобный следующему:
Outputsocat TCP4-LISTEN:8080,fork /dev/null
Нажмите CTRL+C
, чтобы остановить процесс.
Теперь вы создали, исследовали и подключились к сокетам IPv4 и IPv6 на вашей системе. Эти техники и инструменты будут работать на локальных системах разработки или удаленных серверах производства, так что попробуйте экспериментировать с каждым инструментом, чтобы стать более знакомым с тем, как они могут использоваться для тестирования и устранения неполадок с TCP сокетами.
Что такое дейтаграммный сокет?
Дейтаграммные сокеты являются безсоединительными, что означает, что пакеты, отправленные и полученные из сокета, обрабатываются отдельно приложениями. Сетевые дейтаграммные сокеты обычно используют протокол пользовательских дейтаграмм (UDP) для инкапсуляции и передачи данных.
UDP не кодирует информацию о последовательности в заголовках пакетов, и в протокол не встроена коррекция ошибок. Программы, использующие сокеты на основе датаграмм, должны встраивать собственную обработку ошибок и логику упорядочивания данных для обеспечения успешной передачи данных.
Сокеты UDP широко используются серверами доменных имен (DNS). По умолчанию DNS-серверы используют порт 53
для отправки и получения запросов на доменные имена. Пример адреса UDP-сокета для DNS-сервера будет похож на 203.0.113.1:53
.
Примечание: Хотя протокол не включен в человекочитаемую версию адреса сокета, операционные системы отличают адреса сокетов, включая протоколы TCP и UDP как часть адреса. Так что человекочитаемый адрес сокета, например, 203.0.113.1:53
, может использовать любой протокол. Инструменты типа ss
и старая утилита netstat
используются для определения используемого типа сокета.
Протокол сетевого времени (NTP) использует сокет UDP на порту 123
для синхронизации часов между компьютерами. Пример UDP-сокета для протокола NTP будет 203.0.113.1:123
.
Создание датаграммных сокетов
Как и в предыдущем примере с TCP-сокетами, в этом разделе вы снова будете использовать socat
, чтобы эмулировать сервер NTP, прослушивающий запросы на UDP-порту 123
. Затем вы изучите созданные вами сокеты, используя команды ss
и nc
.
Сначала выполните следующие команды socat
, чтобы создать два UDP-сокета, ожидающих подключений на порту 123 с использованием интерфейсов IPv4 и IPv6:
Вы получите вывод подобный следующему, указывающему на два идентификатора процессов socat
, работающих на фоне вашей оболочки. Ваши идентификаторы процессов будут отличаться от выделенных здесь:
Output[1] 465486
[2] 465487
- Каждая команда предварена
sudo
, потому что порты от0
до1024
зарезервированы на большинстве систем.sudo
запускает команду с правами администратора, что позволяетsocat
привязываться к любому порту в зарезервированном диапазоне. - Аргументы
UDP4-LISTEN:123
иUDP6-LISTEN:123
– это тип протокола и порт для использования. Они указывают socat создать сокеты на основе UDP на порту123
как на интерфейсах IPv4, так и IPv6, и ждать входящих данных. Снова любой порт во всем диапазоне от 0 до 65535 является допустимым параметром для UDP-сокетов. - Аргументы
fork
,ipv6only=1
и/dev/null
используются так же, как описано в предыдущем примере с TCP.
Теперь, когда у вас есть два процесса socat
, прослушивающих UDP-порт 123
, вы можете изучить сокеты, используя утилиты ss
и nc
.
Изучение датаграммных сокетов
Для изучения UDP сокетов в современной системе Linux с использованием команды ss
, выполните ее с помощью следующих флагов -4
, -6
и -uln
, чтобы ограничить вывод:
Флаг u
ограничивает вывод только UDP сокетами. Другие флаги такие же, как использованные в предыдущем примере с TCP.
Сначала выполните команду ss -4 -uln
, чтобы изучить IPv4 UDP сокеты, ожидающие подключений на вашей системе:
Вы получите вывод, похожий на следующий:
OutputState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
UNCONN 0 0 0.0.0.0:123 0.0.0.0:*
. . .
В вашем выводе могут быть и другие строки с другими портами, в зависимости от того, какие службы запущены на вашей системе. Подсвеченная часть вывода 0.0.0.0:123
указывает на то, что IPv4 UDP сокет доступен на всех интерфейсах IPv4 на порту 123
. Служба, доступная только на определенном IPv4 адресе, будет показывать только этот IP в выделенном поле, например 203.0.113.1:123
.
Теперь выполните ту же команду ss
, но с флагом -6
:
Вы получите вывод, похожий на следующий:
OutputState Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
UNCONN 0 0 [::]:123 [::]:*
. . .
Могут быть и другие строки с другими портами в вашем выводе в зависимости от служб, работающих в вашей системе. Подсвеченная часть вывода [::]:123
указывает, что сокет TCP IPv6 доступен на всех интерфейсах IPv6 на порту 123
(как указано символами ::
). Служба, доступная только на определенном адресе IPv6, будет показывать только этот IP в подсвеченном поле, например [2604:a880:400:d1::3d3:6001]:123
.
Тестирование датаграммных сокетов
Теперь, когда вы знакомы с тем, как создавать и перечислять сокеты UDP как на интерфейсах IPv4, так и на IPv6, вы можете экспериментировать с подключением к ним. Как и с сокетами TCP, вы можете экспериментировать с сокетами UDP, используя утилиту netcat.
Чтобы подключиться к примеру сокета UDP на порту 123
, созданного в предыдущем разделе этого руководства, выполните следующую команду netcat:
- Флаг
-4
указывает netcat использовать IPv4. - Опция
-u
инструктирует netcat использовать UDP вместо TCP. - Флаг
-v
используется для вывода подробного отчета на ваш терминал. - Опция
-z
гарантирует, что netcat подключится только к сокету, не отправляя никаких данных. - IP-адрес локальной петли
127.0.0.1
используется, так как у вашей системы будет собственный уникальный IP-адрес. Если вы знаете IP-адрес вашей системы, вы также можете провести тест с его использованием. Например, если публичный или частный IP-адрес вашей системы –203.0.113.1
, вы можете использовать его вместо IP-адреса локальной петли.
Вы получите вывод, аналогичный следующему:
OutputConnection to 127.0.0.1 123 port [udp/ntp] succeeded!
Вывод указывает на то, что netcat не получил ошибку от UDP-сокета, прослушивающего локальный IPv4-адрес локальной петли 127.0.0.1
на порту 123
. Отсутствие ответа об ошибке используется для вывода того, что сокет по адресу 127.0.0.1:123
доступен. Это поведение отличается от TCP-сокетов, которым требуется обмен пакетами для подтверждения доступности сокета.
Примечание: Если сокет в этом примере был недоступен, удаленная система вернула бы сообщение типа ICMP 3 (Destination Unreachable) с кодом 3, указывающее, что порт недоступен на удаленном хосте.
Подтверждение доступности сокета на основе отсутствия ответа об ошибке предполагает отсутствие брандмауэров или проблем с подключением, которые блокируют ICMP-трафик. Без отправки, приема и проверки данных приложения через UDP-сокет нет гарантии того, что удаленный UDP-порт открыт и принимает пакеты.
Теперь вы можете повторить тот же тест подключения, но используя IPv6. Выполните следующую команду netcat:
Вы должны получить вывод, аналогичный следующему:
OutputConnection to ::1 123 port [udp/ntp] succeeded!!
Выходные данные указывают на то, что netcat не получил ошибку от UDP-сокета, прослушивающего адрес циклического обхода ::1
IPv6 на порту 123
. Опять же, отсутствие ответа об ошибке используется для вывода вывода, что сокет по адресу ::1:123
доступен.
Чтобы закрыть ваши сокеты, вам нужно будет запустить команду fg
(foreground) для каждого процесса socat, который вы создали. Затем вы будете использовать CTRL+C
, чтобы закрыть каждый socat.
Запустите fg
, чтобы перевести второй экземпляр IPv6 socat
на передний план вашего терминала. Затем выполните CTRL+C
, чтобы закрыть его.
Вы получите вывод подобный следующему:
Outputsudo socat UDP6-LISTEN:123,ipv6only=1,fork /dev/null
Нажмите CTRL+C
, чтобы остановить процесс.
Теперь снова выполните fg
, чтобы закрыть первый IPv4 сокет. У вас будет вывод подобный следующему:
Outputsudo socat UDP4-LISTEN:123,fork /dev/null
Нажмите CTRL+C
, чтобы остановить процесс.
Теперь вы создали, изучили и протестировали IPv4 и IPv6 UDP-сокеты на вашей системе. Попробуйте экспериментировать с каждым инструментом, чтобы стать более знакомым с тем, как они могут быть использованы для тестирования и устранения неполадок с UDP-сокетами.
Что такое Unix-доменный сокет?
Программы, работающие на одном сервере, также могут взаимодействовать друг с другом, используя сокеты домена Unix (UDS). Сокеты домена Unix могут быть основанными на потоках или датаграммах. При использовании сокетов домена данные обмениваются между программами непосредственно в ядре операционной системы через файлы в файловой системе хоста. Для отправки или приема данных с использованием сокетов домена программы читают и записывают в их общий файл сокета, полностью обходя сокеты и протоколы, основанные на сети.
Сокеты домена Unix широко используются системами баз данных, которые не требуют подключения к сетевому интерфейсу. Например, MySQL на Ubuntu по умолчанию использует файл с именем /var/run/mysqld/mysql.sock
для связи с локальными клиентами. Клиенты читают из сокета и пишут в него, как и сам сервер MySQL.
PostgreSQL – еще одна система баз данных, которая использует сокет для локального, несетевого общения. Обычно она по умолчанию использует /run/postgresql/.s.PGSQL.5432
в качестве файла сокета.
Создание сокетов домена Unix
В предыдущих разделах вы исследовали, как TCP используется с потоковыми сокетами, и как UDP используется с датаграммными сокетами. В этом разделе вы будете использовать socat
, чтобы создать как потоковые, так и датаграммные сокеты Unix Domain Sockets, не используя TCP или UDP для инкапсуляции данных, отправляемых по сети. Затем вы изучите созданные вами сокеты с использованием команд ss
и nc
. Наконец, вы узнаете о тестировании Unix Domain Sockets с использованием netcat.
Чтобы начать, выполните следующие команды socat
, чтобы создать два файла сокетов:
- Первая команда указывает socat создать сокет, используя тип адреса
unix-listen
, который создаст потоковый UDS. - Вторая команда указывает
unix-recvfrom
как тип сокета, который создаст датаграммный UDS - Обе команды указывают имя файла после разделителя
:
. Имя файла является адресом самого сокета. Для первого примера потока это/tmp/stream.sock
, а для второго примера датаграммы это/tmp/datagram.sock
. Обратите внимание, что имя сокета произвольно, но полезно, если оно описательно при устранении неполадок. - Аргументы
fork
и/dev/null
используются так же, как описано в разделах с примерами потокового и датаграммного сокетов.
Теперь, когда вы создали свои два UDS сокета, вы можете изучить их, используя утилиты ss
и nc
.
Изучение сокетов домена Unix
Чтобы перечислить все слушающие сокеты домена Unix, выполните команду ss -xln
. Флаг x
гарантирует, что будут отображены только сокеты домена.
Вы получите вывод, подобный следующему:
OutputNetid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
. . .
u_str LISTEN 0 5 /tmp/stream.sock 436470 * 0
u_dgr UNCONN 0 0 /tmp/datagram.sock 433843 * 0
. . .
Обратите внимание на выделенную часть u_str
в строке /tmp/stream/sock
. Это поле указывает, что тип сокета – это основанный на потоке UDS. Вторая строка показывает тип u_dgr
, что означает, что тип сокета – это основанный на датаграммах.
Поскольку сокеты домена Unix являются файлами, обычные права пользователя и группы Linux и контроль доступа могут использоваться для ограничения того, кто может подключаться к сокету. Вы также можете использовать инструменты файловой системы, такие как ls
, mv
, chown
и chmod
, чтобы изучать и управлять файлами UDS. Также могут использоваться инструменты типа SELinux для маркировки файлов UDS различными контекстами безопасности.
Чтобы проверить, является ли файл сокетом UDS, используйте утилиты ls
, file
или stat
. Однако важно отметить, что ни один из этих инструментов не может определить, является ли UDS основанным на потоке или датаграммах. Для получения наиболее полной информации о сокете домена Unix используйте инструмент ss
.
Чтобы изучить сокет на файловой системе, утилита stat
показывает наиболее актуальную информацию. Выполните ее для сокетов, которые вы создали ранее:
Вы получите вывод, подобный следующему:
Output File: /tmp/stream.sock
Size: 0 Blocks: 1 IO Block: 131072 socket
Device: 48h/72d Inode: 1742 Links: 1
Access: (0755/srwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-03-01 18:10:25.025755168 +0000
Modify: 2021-03-01 18:10:25.025755168 +0000
Change: 2021-03-01 18:22:42.678231700 +0000
Birth: -
File: /tmp/datagram.sock
Size: 0 Blocks: 1 IO Block: 131072 socket
Device: 48h/72d Inode: 1743 Links: 1
Access: (0755/srwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-03-01 18:10:25.025755168 +0000
Modify: 2021-03-01 18:10:25.025755168 +0000
Change: 2021-03-01 18:10:25.025755168 +0000
Birth: -
Обратите внимание, что для каждого файла типом является socket
(выделено в крайнем правом столбце вывода), а режим доступа имеет символ s
, предшествующий разрешениям файла.
Утилита ls
также указывает, является ли файл сокетом. Запустите ls -l
, чтобы исследовать файлы:
Вы получите вывод, подобный следующему. Еще раз обратите внимание, что для сокетов режим файла включает символ s
перед полями разрешений файла:
Outputsrwxr-xr-x 1 root root 0 Mar 1 18:10 /tmp/datagram.sock
srwxr-xr-x 1 root root 0 Mar 1 18:10 /tmp/stream.sock
Теперь, когда вы создали сокеты домена Unix и узнали, как их исследовать с помощью утилиты ss
и различных инструментов, основанных на файловой системе, следующим шагом будет тестирование сокетов с использованием такого инструмента, как netcat.
Тестирование сокетов домена Unix
Утилиту netcat можно использовать для подключения к сокетам домена Unix, а также к TCP- и UDP-сокетам, о которых вы уже узнали ранее в этом руководстве. Чтобы подключиться к примерным сокетам, которые вы создали, вам нужно будет указать дополнительный флаг -U
при запуске команды netcat. Этот флаг сообщает netcat, что необходимо подключиться к UDS, в отличие от сокета сети, основанного на TCP или UDP.
Кроме того, если сокет основан на датаграммах, вы будете использовать флаг -u
, чтобы указать netcat использовать датаграммы, как мы узнали в разделе о датаграммных сокетах этого руководства.
Давайте начнем исследование UDS сокетов, подключившись к потоковому сокету с помощью следующей команды:
Опция -U
сообщает netcat, что происходит подключение к Unix Domain Socket.
Опция -z
гарантирует, что netcat подключится только к сокету, не отправляя данных.
/tmp/stream.sock
– это адрес сокета в файловой системе.
Вы не получите никакого вывода от netcat при выполнении команды. Однако, если сокет не доступен, netcat выведет сообщение об ошибке, подобное следующему:
Outputnc: unix connect failed: No such file or directory
nc: /tmp/stream.sock: No such file or directory
Таким образом, отсутствие вывода от netcat при тестировании потокового UDS сокета означает, что подключение было успешным.
Повторите процесс тестирования, на этот раз для дейтаграммного UDS:
Дополнительный флаг -u
добавляется, чтобы сообщить netcat, что удаленный сокет является дейтаграммным. Снова вы не получите никакого вывода в случае успешного теста.
Если сокет по адресу отсутствует, вы получите ошибку, подобную следующей:
Outputnc: unix connect failed: No such file or directory
nc: /tmp/datagram.sock: No such file or directory
Чтобы очистить ваши сокеты, вам нужно выполнить команду fg
(foreground) для каждого процесса socat, который вы создали. Затем вы используете CTRL+C
, чтобы закрыть каждый socat.
Запустите fg
, чтобы перевести дейтаграммный экземпляр socat
в передний план вашего терминала:
Вы получите вывод, подобный следующему:
Outputsocat unix-recvfrom:/tmp/datagram.sock,fork /dev/null
Запустите CTRL+C
, чтобы закрыть его. Вы не получите никакого вывода.
Теперь снова запустите fg
, чтобы очистить первый потоковый UDS сокет.
Снова вы должны получить вывод, подобный следующему:
Outputsocat unix-listen:/tmp/stream.sock,fork /dev/null
Запустите CTRL+C
, чтобы завершить процесс. Вы не получите никакого вывода.
Теперь вы создали, изучили и протестировали сокеты Unix Datagram Sockets на вашей системе. Попробуйте экспериментировать с netcat и socat
, чтобы стать более знакомым с тем, как вы можете отправлять и получать данные через UDS, а также как вы можете тестировать и устранять неполадки в Unix Domain sockets.
Заключение
В этом руководстве вы исследовали, как используются различные виды сокетов в системе Linux. Вы узнали о сокетах, работающих на основе потоков, которые обычно используют TCP для сетевого взаимодействия. Вы также узнали о сокетах, работающих на основе датаграмм, которые используют UDP для отправки данных по сети. Наконец, вы изучили, как Unix Domain Sockets могут быть как на основе потоков, так и на основе датаграмм на локальном сервере.
В каждом разделе вы использовали утилиту ss
, чтобы собирать информацию о сокетах в системе Linux. Вы узнали, как различные флаги, предоставляемые инструментом ss
, могут помочь вам ограничить его вывод до определенных типов сокетов при изучении сокетов на системе.
Наконец, вы использовали инструменты netcat и socat для создания и подключения к каждому из трех различных типов сокетов, обсуждаемых в этом руководстве. Утилита netcat широко используется для подключения к сокетам, но также может создавать сокеты. В ее документации (man nc) содержится множество примеров того, как ее можно использовать в любом из режимов. Утилита socat является более продвинутым инструментом, который можно использовать для подключения к множеству различных типов сокетов, не описанных в данном руководстве. В ее документации (man socat) также содержится множество примеров различных способов ее использования.
Понимание того, что такое сокеты и как они работают, является ключевым навыком системного администратора. Инструменты и техники, с которыми вы экспериментировали в этом руководстве, помогут вам лучше понять сокеты и научиться устранять неполадки, если ваши серверы и приложения неправильно обмениваются данными.
Source:
https://www.digitalocean.com/community/tutorials/understanding-sockets