Отличие unix сокетов от tcp сокетов

Обновлено: 06.07.2024

Сокеты (англ. socket — разъём) — название программного интерфейса для обеспечения обмена данными между процессами. Процессы при таком обмене могут исполняться как на одной ЭВМ, так и на различных ЭВМ, связанных между собой сетью. Сокет — абстрактный объект, представляющий конечную точку соединения.

Принципы сокетов¶

Каждый процесс может создать слушающий сокет (серверный сокет) и привязать его к какому-нибудь порту операционной системы (в UNIX непривилегированные процессы не могут использовать порты меньше 1024). Слушающий процесс обычно находится в цикле ожидания, то есть просыпается при появлении нового соединения. При этом сохраняется возможность проверить наличие соединений на данный момент, установить тайм-аут для операции и т.д.

Каждый сокет имеет свой адрес. ОС семейства UNIX могут поддерживать много типов адресов, но обязательными являются INET-адрес и UNIX-адрес. Если привязать сокет к UNIX-адресу, то будет создан специальный файл (файл сокета) по заданному пути, через который смогут сообщаться любые локальные процессы путём чтения/записи из него (см. Доменный сокет Unix). Сокеты типа INET доступны из сети и требуют выделения номера порта.

Обычно клиент явно подсоединяется к слушателю, после чего любое чтение или запись через его файловый дескриптор будут передавать данные между ним и сервером.

Основные функции¶

socket()¶

Создаёт конечную точку соединения и возвращает файловый дескриптор. Принимает три аргумента:

domain указывающий семейство протоколов создаваемого сокета

  • AF_INET для сетевого протокола IPv4
  • AF_INET6 для IPv6
  • AF_UNIX для локальных сокетов (используя файл)

type

  • SOCK_STREAM (надёжная потокоориентированная служба (сервис) или потоковый сокет)
  • SOCK_DGRAM (служба датаграмм или датаграммный сокет)
  • SOCK_RAW (Сырой сокет — сырой протокол поверх сетевого уровня).

protocol

Протоколы обозначаются символьными константами с префиксом IPPROTO_* (например, IPPROTO_TCP или IPPROTO_UDP). Допускается значение protocol=0 (протокол не указан), в этом случае используется значение по умолчанию для данного вида соединений.

Функция возвращает −1 в случае ошибки. Иначе, она возвращает целое число, представляющее присвоенный дескриптор.

Пример на Python

Связывает сокет с конкретным адресом. Когда сокет создается при помощи socket(), он ассоциируется с некоторым семейством адресов, но не с конкретным адресом. До того как сокет сможет принять входящие соединения, он должен быть связан с адресом. bind() принимает три аргумента:

  1. sockfd — дескриптор, представляющий сокет при привязке
  2. serv_addr — указатель на структуру sockaddr, представляющую адрес, к которому привязываем.
  3. addrlen — поле socklen_t, представляющее длину структуры sockaddr.

Возвращает 0 при успехе и −1 при возникновении ошибки.

Пример на Python

Автоматическое получение имени хоста.

listen()¶

Подготавливает привязываемый сокет к принятию входящих соединений. Данная функция применима только к типам сокетов SOCK_STREAM и SOCK_SEQPACKET. Принимает два аргумента:

  1. sockfd — корректный дескриптор сокета.
  2. backlog — целое число, означающее число установленных соединений, которые могут быть обработаны в любой момент времени. Операционная система обычно ставит его равным максимальному значению.

После принятия соединения оно выводится из очереди. В случае успеха возвращается 0, в случае возникновения ошибки возвращается −1.

Пример на Python

accept()¶

Используется для принятия запроса на установление соединения от удаленного хоста. Принимает следующие аргументы:

  1. sockfd — дескриптор слушающего сокета на принятие соединения.
  2. cliaddr — указатель на структуру sockaddr, для принятия информации об адресе клиента.
  3. addrlen — указатель на socklen_t, определяющее размер структуры, содержащей клиентский адрес и переданной в accept(). Когда accept() возвращает некоторое значение, socklen_t указывает сколько байт структуры cliaddr использовано в данный момент.

Функция возвращает дескриптор сокета, связанный с принятым соединением, или −1 в случае возникновения ошибки.

Пример на Python

connect()¶

Устанавливает соединение с сервером.

Некоторые типы сокетов работают без установления соединения, это в основном касается UDP-сокетов. Для них соединение приобретает особое значение: цель по умолчанию для посылки и получения данных присваивается переданному адресу, позволяя использовать такие функции как send() и recv() на сокетах без установления соединения.

Загруженный сервер может отвергнуть попытку соединения, поэтому в некоторых видах программ необходимо предусмотреть повторные попытки соединения.

Возвращает целое число, представляющее код ошибки: 0 означает успешное выполнение, а −1 свидетельствует об ошибке.

Пример на Python

Передача данных¶

Для передачи данных можно пользоваться стандартными функциями чтения/записи файлов read и write, но есть специальные функции для передачи данных через сокеты:

Сокет UNIX представляет собой механизм межпроцессного взаимодействия , который позволяет осуществлять обмен данными между двунаправленных процессов , работающих на одной и той же машине.

Сокеты IP (особенно сокеты TCP / IP) - это механизм, позволяющий осуществлять связь между процессами по сети. В некоторых случаях вы можете использовать сокеты TCP / IP для связи с процессами, запущенными на одном компьютере (с помощью интерфейса обратной связи).

Доменные сокеты UNIX знают, что они выполняются в одной и той же системе, поэтому они могут избежать некоторых проверок и операций (например, маршрутизации); что делает их быстрее и легче, чем IP-сокеты. Поэтому, если вы планируете взаимодействовать с процессами на одном хосте, это лучший вариант, чем IP-сокеты.

Редактирование: Согласно комментарию Нильса Тедтманна : сокеты домена UNIX подчиняются разрешениям файловой системы, в то время как сокеты TCP можно контролировать только на уровне фильтра пакетов.

Возможно, добавьте, что сокеты домена UNIX подчиняются разрешениям файловой системы, а сокеты TCP - нет. В результате гораздо проще регулировать, какие пользователи имеют доступ к сокету домена UNIX, чем к сокету TCP. @pQd, чувак, можешь ли ты назвать это Unix IPC вместо Unix Sockets? @Pacerier Unix-сокеты - это просто один из способов достижения Unix IPC (совместно используемой межпроцессной памяти среди других), поэтому было бы неправильно называть unix-сокеты Unix IPC. TCP-сокеты тоже обрабатываются Unix? TCP-сокеты является частью спецификации протокола TCP или любой протокол может использовать IP-сокеты? @Federico Я опубликовал ответ, который пытается ответить на ваш запрос. Если вам требуется больше информации, пожалуйста, отправьте новый вопрос.

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

Unix-сокеты не существуют в Windows. netstat Однако работает на Windows. @apache, похожая вещь в Windows называется "Именованные каналы". @expert, именованные каналы в Windows равны именованным каналам в Unix. Сокеты IPC в Unix не имеют аналогов в Windows

В чем разница между сокетом Unix и сокетом TCP / IP?

Разъем TCP / IP используется для связи по сетям TCP / IP. Подключенный TCP-сокет идентифицируется по комбинации локального IP-адреса, локального порта, удаленного IP-адреса и удаленного порта. Прослушивающий сокет TCP определяется локальным портом и, возможно, локальным IP. AIUI по крайней мере в сокетах Linux / TCP / IP всегда приводит к генерации и декодированию пакетов TCP / IP, даже если клиент и сервер находятся на одном компьютере.

Сокет домена unix (иногда сокращенный до сокета unix), с другой стороны, работает на одном компьютере. Прослушивающие сокеты живут в иерархии файловой системы, и доступ к ним может контролироваться разрешениями файловой системы.

Кроме того, процесс, принимающий соединение через сокет Unix, может определить идентификатор пользователя процесса, который подключается. Это может избежать необходимости в шаге аутентификации. Вместо того, чтобы генерировать пароль для вашего сервера базы данных и включать его копию в код вашего веб-приложения, вы можете просто сообщить серверу базы данных, что пользователь, выполняющий веб-приложение, имеет доступ к соответствующей учетной записи пользователя в базе данных.

TCP-сокеты тоже обрабатываются Unix?

TCP-сокеты являются частью спецификации протокола TCP

Спецификации интернет-протокола имеют тенденцию касаться только того, что происходит в сети, спецификация TCP содержит определение Socket, но это определение не совпадает с тем, как термин используется в «API сокетов».

«API сокетов», как мы знаем, было введено BSD, но позже было скопировано повсеместно и включено как часть стандарта posix. Основные вещи для сокетов TCP и UDP, как правило, одинаковы для разных платформ, но более сложные вещи и вещи, взаимодействующие с другими частями ОС, различаются, например, в Unix-подобных системах сокет идентифицируется дескриптором файла и может быть прочитанным / записанным файловыми API, это не относится к Windows.

Некоторые расширения API сокетов были задокументированы в rfcs, но эти RFC являются только «информационными».

или любой протокол может использовать IP-сокеты?

Когда приложение явно создает сокет, используя функцию «сокет» (сокеты также создаются функцией accept), он передает три параметра: «домен», «тип» и «протокол». Между ними эти три параметра могут использоваться для выбора множества различных типов сокетов.

Разница между сокетом домена Unix и сокетом IP (tcp / ip)

Независимо от того, чем вы занимаетесь разработкой, сетевое программирование неотделимо, и сетевое программирование часто включает сокеты. Socket был первоначально разработан Калифорнийским университетом в Беркли и в основном использовался для реализации межпроцессного взаимодействия в 4.2BSD. Существует два основных типа сокетов: сокет домена Unix и сокет IP. Так в чем же между ними разница?

Доменный сокет Unix, также называемый IPC socket (сокет межпроцессного взаимодействия, то есть сокет межпроцессного взаимодействия), используемый для обмена данными между разными процессами на одном и том же хосте. PosixСтандартные компоненты системы. Он может передавать поток байтов (поток байтов, SOCK_STREAM, TCP) или дейтаграмму (дейтаграмма, SOCK_DGRAM, UDP). Помимо передачи данных, вы также можете использовать сокет домена Unix для передачи дескрипторов файлов ( file descriptor)。

IP-сокет должен использовать транспортный уровень хоста (tcp), который может использоваться для связи между различными процессами на одном и том же хосте, а также может использоваться для связи между разными хостами в сети.

Давайте сначала рассмотрим вариант использования для настройки сокета для php-fpm для взаимодействия с Nginx:

В этом случае PHP и Nginx, работающие на одном компьютере, должны взаимодействовать. Есть два способа добиться этого: первый - это IP-сокет, который реализуется с помощью локального адреса обратной петли 127.0.0.1 и порта; второй - через сокет домена unix. достичь. Какой из них более эффективен?

IP-сокет на основе локального хоста должен реализовывать все каналы межсетевого взаимодействия хоста, включая установление соединения сокета, накладные расходы ACk, управление потоком TCP, инкапсуляцию / деинкапсуляцию и маршрутизацию. В этом процессе будет два переключения контекста, потому что использование сетевого уровня для передачи данных требует вызова системного вызова, а вызов системного вызова вызовет прерывание, в результате чего произойдет переключение контекста; другой процесс получает запрос на соединение от сетевого уровня, он также будет Генерируется системное прерывание, приводящее к переключению контекста. Вышеупомянутый процесс приводит к накладным расходам на два переключения контекста, а также к различным другим накладным расходам.

Сокеты Unix — это форма связи между двумя процессами, которая отображается в виде файла на диске. Этот файл может использоваться другими программами для установления очень быстрых соединений между двумя или более процессами без каких-либо сетевых накладных расходов.


Что такое сокеты?

Сокеты — это прямая связь между двумя процессами. Представьте, что вы хотите позвонить своему другу по дороге; вы можете сделать звонок, направив его через вашу телефонную компанию и обратно в их дом, или вы можете провести провод прямо в их дом и отключить посредника. Последнее, очевидно, непрактично в реальной жизни, но в мире Unix очень распространено устанавливать эти прямые связи между программами.

Собственное имя для сокетов unix — сокеты домена Unix (Unix Domain Sockets), потому что все они находятся на одном компьютере. В некотором смысле сокеты — это сеть, полностью содержащаяся в ядре; вместо того, чтобы использовать сетевые интерфейсы и соответствующие накладные расходы для отправки данных, те же самые данные могут быть отправлены напрямую между программами.

Несмотря на создание файлов на диске, сокеты Unix на самом деле не записывают данные, которые они отправляют на диск, так как это было бы слишком медленно. Вместо этого все данные хранятся в памяти ядра; единственная цель файла сокета — поддерживать ссылку на сокет и давать ему разрешения файловой системы для управления доступом. В современных системах сокеты обычно расположены в директории /usr/lib/systemd/system/. Например, сокет MariaDB обычно находится по адресу:


Этот файл ничего не содержит, и вы не должны изменять его напрямую, за исключением разрешений, где это применимо. Это просто имя.

Как работают сокеты?

Сокеты просто предоставляют фактическое оборудование для перемещения данных. Сокеты на основе TCP называются потоковыми сокетами, куда все данные будут поступать по порядку. Сокеты на основе UDP — это сокеты для дейтаграмм, для которых порядок (или даже доставка) не гарантируется. Существуют также необработанные (raw) сокеты, которые не имеют каких-либо ограничений и используются для реализации различных протоколов и утилит, которые должны проверять низкоуровневый сетевой трафик, например Wireshark.

Сокеты обычно по-прежнему используют TCP или UDP, поскольку они не являются чем-то особенным, кроме причудливого канала внутри ядра. TCP и UDP — это транспортные протоколы, которые определяют, как данные передаются с места на место, но не заботятся о том, что это за данные. TCP и UDP обеспечивают платформу для большинства других протоколов, таких как FTP, SMTP и RDP, которые работают на более высоких уровнях.

Приложение может использовать несколько иную реализацию TCP; потоковые сокеты используют протокол SOCK_STREAM, который TCP также использует для транспорта почти всё время, и хотя они в основном взаимозаменяемы, технически они немного отличаются. Хотя это низкоуровневый материал и на самом деле это не то, о чем вам придётся беспокоиться, просто знайте, что большая часть трафика, отправляемого через сокеты домена UNIX, основана на TCP или UDP или, по крайней мере, очень похожа на трафик этих транспортных протоколов, и TCP отправляется через сокеты домена UNIX быстрее, чем TCP через сетевые интерфейсы, такие как порты.

Использование сокетов на практике

Сокеты Unix обычно используются в качестве альтернативы сетевым TCP-соединениям, когда процессы выполняются на одном компьютере. Данные обычно по-прежнему отправляются по тем же протоколам; но поскольку они просто остаются на той же машине, в том же домене (отсюда и название сокеты домена UNIX), поэтому им никогда не нужно беспокоить петлевой (loopback) сетевой интерфейс для подключения к самому себе.

Самым ярким примером этого является Redis, чрезвычайно быстрое хранилище значений ключей, которое полностью работает в памяти. Redis часто используется на том же сервере, который обращается к нему, поэтому обычно можно использовать сокеты. На таких низких уровнях и с учётом того, насколько быстр Redis, сокеты обеспечивают повышение производительности на 25% в некоторых синтетических тестах.

Если вы подключаетесь к базе данных MySQL, вы также можете использовать сокет. Обычно вы подключаетесь к host:port из удалённой системы, но если вы подключаетесь к базе данных на том же сервере (например, REST API обращается к базе данных), вы можете использовать сокеты для ускорения. Это не повлияет на нормальное использование, но очень заметно при нагрузке, более 20% на 24 ядрах высокого класса со 128 одновременными пользователями и миллионом запросов в секунду. Увидите ли вы выгоду от сокетов при таких условиях — это совсем другое дело, но на этом этапе, вероятно, всё равно придётся заняться репликацией и балансировкой нагрузки.

Если вы хотите работать с сокетами вручную, вы можете использовать утилиту socat, чтобы открыть их через сетевые порты:

Это технически противоречит назначению сокетов домена Unix, но может использоваться для отладки на транспортном уровне.

Читайте также: