Понимание сокетов

Введение

Сокеты – это способ обеспечения межпроцессного взаимодействия между программами, запущенными на сервере, или между программами, работающими на разных серверах. Обмен данными между серверами осуществляется с использованием сетевых сокетов, которые используют Протокол Интернета (IP) для инкапсуляции и обработки отправки и приема данных.

Сетевые сокеты как на клиенте, так и на сервере обозначаются своим сокетным адресом. Адрес представляет собой уникальное сочетание транспортного протокола, такого как Протокол Управления Передачей (TCP) или Протокол Пользовательских Датаграмм (UDP), IP-адреса и номера порта.

В этом руководстве вы узнаете о следующих различных типах сокетов, используемых для межпроцессного взаимодействия:

  • Сокеты потоковой передачи, которые используют TCP в качестве транспортного протокола
  • Сокеты дейтаграмм, которые используют UDP в качестве транспортного протокола
  • Сокеты доменов Unix, которые используют локальные файлы для отправки и приема данных вместо сетевых интерфейсов и IP-пакетов.

В каждом разделе этого руководства вы также узнаете, как перечислить соответствующие типы сокетов в системе Linux. Вы будете изучать каждый тип сокета с использованием различных инструментов командной строки.

Предварительные требования

Примеры в этом руководстве были проверены на сервере Ubuntu 20.04. Вы можете следовать этому руководству, используя большинство современных дистрибутивов Linux на локальном компьютере или удаленном сервере, при условии, что у вас установлена эквивалентная версия каждого из необходимых инструментов для вашего дистрибутива.

Чтобы начать использовать Ubuntu 20.04, вам понадобится один сервер, который был настроен в соответствии с нашим Руководством по начальной настройке сервера для Ubuntu 20.04.

Вам также понадобятся несколько других пакетов, чтобы исследовать сокеты на вашей системе. Убедитесь, что кеш пакетов вашей системы обновлен с помощью команды apt update:

  1. sudo apt update

Затем установите необходимые пакеты с помощью этой команды:

  1. sudo apt install iproute2 netcat-openbsd socat

Пакет 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:

  1. socat TCP4-LISTEN:8080,fork /dev/null&
  2. socat TCP6-LISTEN:8080,ipv6only=1,fork /dev/null&
  • Аргументы 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-ориентированные сокеты, слушающие соединения на вашей системе:

  1. ss -4 -tln

Вы получите вывод, подобный следующему:

Output
State 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:

  1. ss -6 -tln

Вы получите вывод, подобный следующему:

Output
State 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, выполните следующую команду:

  1. nc -4 -vz 127.0.0.1 8080
  • Флаг -4 сообщает netcat использовать IPv4.
  • Флаг -v используется для печати подробного вывода на ваш терминал.
  • Опция -z обеспечивает подключение netcat только к сокету, без отправки данных.
  • Используется локальный адрес обратной петли 127.0.0.1, поскольку у вашей системы есть собственный уникальный IP-адрес. Если вы знаете IP-адрес вашей системы, вы можете также провести тестирование с его использованием. Например, если публичный или частный IP-адрес вашей системы – 203.0.113.1, вы можете использовать его вместо IP-адреса обратной петли.

Вы получите вывод, подобный следующему:

Output
Connection 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:

  1. nc -6 -vz ::1 8080

Вы должны получить вывод, аналогичный следующему:

Output
Connection 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, чтобы закрыть его.

  1. fg

Вы получите вывод, подобный следующему:

Output
socat TCP6-LISTEN:8080,ipv6only=1,fork /dev/null

Нажмите CTRL+C, чтобы остановить процесс.

Теперь снова запустите fg, чтобы очистить первый IPv4 сокет. У вас должен быть вывод, подобный следующему:

Output
socat 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:

  1. sudo socat UDP4-LISTEN:123,fork /dev/null&
  2. sudo socat UDP6-LISTEN:123,ipv6only=1,fork /dev/null&

Вы получите вывод подобный следующему, указывающему на два идентификатора процессов 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 сокеты, ожидающие подключений на вашей системе:

  1. ss -4 -uln

Вы получите вывод, похожий на следующий:

Output
State 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:

  1. ss -6 -uln

Вы получите вывод, похожий на следующий:

Output
State 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:

  1. nc -4 -u -vz 127.0.0.1 123
  • Флаг -4 указывает netcat использовать IPv4.
  • Опция -u инструктирует netcat использовать UDP вместо TCP.
  • Флаг -v используется для вывода подробного отчета на ваш терминал.
  • Опция -z гарантирует, что netcat подключится только к сокету, не отправляя никаких данных.
  • IP-адрес локальной петли 127.0.0.1 используется, так как у вашей системы будет собственный уникальный IP-адрес. Если вы знаете IP-адрес вашей системы, вы также можете провести тест с его использованием. Например, если публичный или частный IP-адрес вашей системы – 203.0.113.1, вы можете использовать его вместо IP-адреса локальной петли.

Вы получите вывод, аналогичный следующему:

Output
Connection 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:

  1. nc -6 -u -vz ::1 123

Вы должны получить вывод, аналогичный следующему:

Output
Connection 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, чтобы закрыть его.

  1. fg

Вы получите вывод подобный следующему:

Output
sudo socat UDP6-LISTEN:123,ipv6only=1,fork /dev/null

Нажмите CTRL+C, чтобы остановить процесс.

Теперь снова выполните fg, чтобы закрыть первый IPv4 сокет. У вас будет вывод подобный следующему:

Output
sudo 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, чтобы создать два файла сокетов:

  1. socat unix-listen:/tmp/stream.sock,fork /dev/null&
  2. socat unix-recvfrom:/tmp/datagram.sock,fork /dev/null&
  • Первая команда указывает socat создать сокет, используя тип адреса unix-listen, который создаст потоковый UDS.
  • Вторая команда указывает unix-recvfrom как тип сокета, который создаст датаграммный UDS
  • Обе команды указывают имя файла после разделителя :. Имя файла является адресом самого сокета. Для первого примера потока это /tmp/stream.sock, а для второго примера датаграммы это /tmp/datagram.sock. Обратите внимание, что имя сокета произвольно, но полезно, если оно описательно при устранении неполадок.
  • Аргументы fork и /dev/null используются так же, как описано в разделах с примерами потокового и датаграммного сокетов.

Теперь, когда вы создали свои два UDS сокета, вы можете изучить их, используя утилиты ss и nc.

Изучение сокетов домена Unix

Чтобы перечислить все слушающие сокеты домена Unix, выполните команду ss -xln. Флаг x гарантирует, что будут отображены только сокеты домена.

  1. ss -xln

Вы получите вывод, подобный следующему:

Output
Netid 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 показывает наиболее актуальную информацию. Выполните ее для сокетов, которые вы создали ранее:

  1. stat /tmp/stream.sock /tmp/datagram.sock

Вы получите вывод, подобный следующему:

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, чтобы исследовать файлы:

  1. ls -l /tmp/stream.sock /tmp/datagram.sock

Вы получите вывод, подобный следующему. Еще раз обратите внимание, что для сокетов режим файла включает символ s перед полями разрешений файла:

Output
srwxr-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 сокетов, подключившись к потоковому сокету с помощью следующей команды:

  1. nc -U -z /tmp/stream.sock

Опция -U сообщает netcat, что происходит подключение к Unix Domain Socket.
Опция -z гарантирует, что netcat подключится только к сокету, не отправляя данных.
/tmp/stream.sock – это адрес сокета в файловой системе.

Вы не получите никакого вывода от netcat при выполнении команды. Однако, если сокет не доступен, netcat выведет сообщение об ошибке, подобное следующему:

Output
nc: unix connect failed: No such file or directory nc: /tmp/stream.sock: No such file or directory

Таким образом, отсутствие вывода от netcat при тестировании потокового UDS сокета означает, что подключение было успешным.

Повторите процесс тестирования, на этот раз для дейтаграммного UDS:

  1. nc -uU -z /tmp/datagram.sock

Дополнительный флаг -u добавляется, чтобы сообщить netcat, что удаленный сокет является дейтаграммным. Снова вы не получите никакого вывода в случае успешного теста.

Если сокет по адресу отсутствует, вы получите ошибку, подобную следующей:

Output
nc: 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 в передний план вашего терминала:

  1. fg

Вы получите вывод, подобный следующему:

Output
socat unix-recvfrom:/tmp/datagram.sock,fork /dev/null

Запустите CTRL+C, чтобы закрыть его. Вы не получите никакого вывода.

Теперь снова запустите fg, чтобы очистить первый потоковый UDS сокет.

Снова вы должны получить вывод, подобный следующему:

Output
socat 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