Что такое socket linux
Что такое сокеты Unix и как они работают?
Сокеты 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, но может использоваться для отладки на транспортном уровне.
Что такое socket linux
Вызов socket(2) создаёт сокет, connect(2) соединяет сокет с удалённым сокетным адресом, bind(2) привязывает сокет к локальному адресу, listen(2) сообщает сокету, что должны приниматься новые соединения, а accept(2) используется для получения нового сокета для нового входящего соединения. Вызов socketpair(2) возвращает два соединённых анонимных сокета (реализовано только для некоторых локальных семейств, например AF_UNIX).
Вызовы send(2), sendto(2) и sendmsg(2) отправляют данные в сокет, а recv(2), recvfrom(2) и recvmsg(2) принимают данные из сокета. Вызовы poll(2) и select(2) ожидают поступления данных или готовятся к передаче данных. Кроме того, для чтения и записи данных могут использоваться стандартные операции ввода-вывода: write(2), writev(2), sendfile(2), read(2) и readv(2).
Вызов getsockname(2) возвращает адрес локального сокета, а getpeername(2) возвращает адрес удалённого сокета. Вызовы getsockopt(2) и setsockopt(2) используются для установки или считывания параметров протокола или уровня сокетов. Вызов ioctl(2) может быть использован для установки или чтения некоторых других параметров.
Вызов close(2) используется для закрытия сокета. Вызов shutdown(2) закрывает части полнодуплексного сокетного соединения.
Перемещение (seeking), или вызовы pread(2) и pwrite(2) с ненулевой позицией, для сокетов не поддерживается.
Для сокетов возможно создание неблокирующего ввода/вывода путём установки в файловый дескриптор сокета флага O_NONBLOCK с помощью вызова fcntl(2). При этом все блокировавшие раньше операции, будут возвращать EAGAIN (операция должна быть повторена позднее); connect(2) возвратит ошибку EINPROGRESS. Пользователь может подождать наступления различных событий через poll(2) или select(2).
События ввода-вывода | ||
Событие | Флаг poll | Когда происходит |
Чтение | POLLIN | Поступили новые данные |
Чтение | POLLIN | Установка соединения выполнена (для сокетов, ориентированных на соединение) |
Чтение | POLLHUP | Другая сторона инициировала запрос на разъединение |
Чтение | POLLHUP | Соединение разорвано (только для протоколов, ориентированных на соединение). Если производится запись в сокет, то также посылается сигнал SIGPIPE |
Запись | POLLOUT | Сокет имеет достаточно места в буфере отправки для записи в него новых данных |
Чтение/Запись | POLLIN| POLLOUT | Исходящий вызов connect(2) завершён |
Чтение/Запись | POLLERR | Произошла асинхронная ошибка |
Чтение/Запись | POLLHUP | Другая сторона закрыла (shut down) одно направление |
Исключение | POLLPRI | Пришли неотложные данные. При этом посылается сигнал SIGURG |
Альтернативе poll(2) и select(2) в ядре существует возможность информировать приложение о событиях с помощью сигнала SIGIO. Для этого необходимо установить с помощью fcntl(2) в файловом дескрипторе сокета флаг O_ASYNC, а также назначить с помощью sigaction(2) корректный обработчик сигнала SIGIO. Смотрите ниже раздел Сигналы.
Структуры адреса сокета
Для передачи сокетного адреса любого типа через программный интерфейс сокетов служит тип struct sockaddr. Целью данного типа является приведение типов сокетных адресов определённого домена к «общему» типу, что позволяет избежать предупреждений компилятора о несовпадении типов в вызовах API сокетов.
Также, программный интерфейс сокетов предоставляет тип данных struct sockaddr_storage. Данный тип удобен для размещения всех поддерживаемых структур сокетных адресов определённого домена; он достаточно большой и имеет корректное выравнивание (в частности, он позволяет хранить сокетные адреса IPv6). Для определения типа сокетного адреса, который хранится в структуре, служит следующее поле:
Структура sockaddr_storage полезна для программ, которые должны работать с сокетными адресами единообразно (например, в программах, использующих одновременно сокетные адреса IPv4 и IPv6).
Параметры сокетов
До Linux 3.8, данный параметр сокета можно было устанавливать, но нельзя прочитать с помощью getsockopt(2). Начиная с Linux 3.8 он доступен для чтения. Аргумент optlen должен содержать размер буфера, способного разместить имя устройства; рекомендуемое значение — IFNAMSZ байт. Реальная длина имени устройства возвращается обратно через аргумент optlen.
SO_BROADCAST Задать или считать флаг широковещания. Если он установлен, то через датаграммные сокеты разрешено отправлять пакеты на широковещательный адрес. Этот параметр не действует на потоковые сокеты. SO_BSDCOMPAT Разрешить совместимость по ошибкам с BSD. Используется модулем протокола UDP в Linux версии 2.0 и 2.2. Если включено, то полученные UDP-сокетом ошибки ICMP не будут передаваться пользовательской программе. В последний версиях ядер поддержка этого параметра удалена: в Linux 2.4 он игнорируется, а в Linux 2.6 при использовании в программе для него генерируется предупреждение ядра (printk()). В Linux 2.0 также включён параметр совместимости по ошибкам с BSD и для неструктурированных сокетов (произвольное изменение заголовка, пропуск флага широковещательной передачи), но в Linux 2.2 это было удалено. SO_DEBUG Включить отладку сокета. Разрешено только процессам с мандатом CAP_NET_ADMIN или имеющим нулевой идентификатор эффективного пользователя. SO_DOMAIN (начиная с Linux 2.6.32) Получить доменный сокет в виде целого числа; пример возвращаемого значения: AF_INET6. Подробней смотрите в socket(2). Этот параметр сокета доступен только для чтения. SO_ERROR Получить и очистить ожидающую обработки ошибку сокета. Этот параметр сокета доступен только для чтения. Ожидает целое число. SO_DONTROUTE Не выполнять отправку через шлюз, посылать только на машины, соединенные напрямую. Тот же эффект может быть достигнут путём установки для сокета флага MSG_DONTROUTE во время вызова send(2). В качестве параметра ожидается целочисленный логический флаг. SO_KEEPALIVE Включить отправку «поддерживающих» (keep-alive) сообщений для сокетов, ориентированных на соединение. Ожидается целочисленный логический флаг. SO_LINGER Задать или считать параметр SO_LINGER. Аргументом является структура linger.
Если этот параметр установлен, то close(2) или shutdown(2) не вернут управление до тех пор, пока не будут отправлены все сообщения в очереди сокета или до истечения времени задержки (linger). В противном случае вызовы вернут управление немедленно и закрытие будет произведено в фоновом режиме. Если сокет закрывается как часть вызова exit(2), то задержка всегда происходит в фоновом режиме. SO_MARK (начиная с Linux 2.6.25) Устанавливать метку на каждый пакет, отправленный через сокет (похоже на цель netfilter MARK, но для сокетов). Изменение метки можно использовать для маршрутизации на основе меток не задействуя netfilter или для фильтрации пакетов. Для установки этого параметра требуется мандат CAP_NET_ADMIN. SO_OOBINLINE Если включён этот параметр, то внепоточные данные помещаются непосредственно во входной поток данных. В противном случае внепоточные данные передаются только, если во время приёма установлен флаг MSG_OOB. SO_PASSCRED Включить или выключить приём управляющего сообщения SCM_CREDENTIALS. Подробней смотрите в unix(7). SO_PEEK_OFF (начиная с Linux 3.4) Этот параметр, который пока поддерживается только для сокетов unix(7), устанавливает значение «смещения выборки» (peek offset) для системного вызова recv(2), когда он используется с флагом MSG_PEEK.
Если этому параметру присваивается положительное значение или ноль, то следующая выборка данных из очереди сокета произойдёт по байтовому смещению, определяемому значением этого параметра. В то же время, «смещение выборки» будет увеличено на количество байт, выбранных из очереди, то есть последовательные операции выборки возвращают следующие данные из очереди.
Если данные удалены из начала очереди с помощью вызова recv(2) (или подобного) без флага MSG_PEEK, то «смещение выборки» будет уменьшено на количество удалённых байт. Другими словами, приём данных без флага MSG_PEEK корректирует «смещение выборки» относительно поддерживаемого относительного положения данных в очереди, и последующая выборка возвратит данные, которые были бы получены, если бы данные не удалялись.
Для датаграммных сокетов, если «смещение выборки» указывает в середину пакета, то возвращаемые данные маркируются флагом MSG_TRUNC.
В следующем примере показано использование SO_PEEK_OFF. Предположим, в очереди потокового сокета есть входные данные:
Следующая последовательность вызовов recv(2) выполнила бы то, что описано в комментариях:
Для сокетов TCP данный параметр позволяет accept(2) распределить нагрузку в многонитиевом сервере, назначая разные слушатели сокета в каждой нити. Это улучшает распределение нагрузки по сравнении с обычными методами, например с одной принимающей нитью accept(2), которая распределяет соединения, или с несколькими нитями, которые конкурируют за accept(2) единого сокета.
Для сокетов UDP использование данного параметра может улучшить распределение входящих датаграмм по нескольким процессам (или нитям) по сравнении с обычным методом с несколькими процессами, которые конкурируют при приёме датаграмм из единого сокета.
SO_RXQ_OVFL (начиная с Linux 2.6.33) Указывает, что к принятым skbs должно быть прикреплено вспомогательное сообщение (cmsg) с беззнаковым 32-битным значением, которое обозначает количество пакетов, отброшенных сокетом между последним принятым пакетом и этим принятым пакетом. SO_SNDBUF Задать или считать максимальный размер буфера отправки сокета (в байтах). Ядро удваивает это значение (для пространства под учёт ресурсов (bookkeeping overhead)) при установке этого параметра с помощью setsockopt(2), и это удвоенное значение возвращается getsockopt(2). Значение по умолчанию устанавливается через файл /proc/sys/net/core/wmem_default, а максимальное возможное значение устанавливается через файл /proc/sys/net/core/wmem_max. Минимальное (удвоенное) значение для этого параметра равно 2048. SO_SNDBUFFORCE (начиная Linux 2.6.14) С помощью этого параметра сокета привилегированный (CAP_NET_ADMIN) процесс может выполнить ту же работу, что и с помощью SO_SNDBUF, но возможно превысить ограничение wmem_max. SO_TIMESTAMP Включить или выключить приём управляющего сообщения SO_TIMESTAMP. Управляющее сообщение метки времени посылается с уровнем SOL_SOCKET, а поле cmsg_data выражено структурой struct timeval, обозначающей время приёма последнего пакета, переданного пользователю в этом вызове. Подробней об управляющих сообщениях смотрите в cmsg(3). SO_TYPE Получить тип сокета в виде целого числа (например, SOCK_STREAM). Этот параметр сокета доступен только для чтения. SO_BUSY_POLL (начиная с Linux 3.11) Задаёт приблизительный интервал в микросекундах для задержки опроса при блокирующем приёме при отсутствии данных. Увеличение этого значения требует мандата CAP_NET_ADMIN. Значение по умолчанию данного параметра управляется через файл /proc/sys/net/core/busy_read.
Значение в файле /proc/sys/net/core/busy_poll определяет как долго select(2) и poll(2) задержат опрос, если они работают с сокетами с установленным SO_BUSY_POLL и отсутствуют события для извещения.
В обоих случаях опрос с задержкой (busy polling) будет завершён только, когда сокет примет все данные из сетевого устройства, которое поддерживает этот параметр.
Хотя опрос с задержкой может уменьшить время ожидания в некоторых приложениях, этим нужно пользоваться с осторожностью, так как его использование увеличит нагрузку на ЦП и энергопотребление.
Сигналы
Если был произведён вызов fcntl(2) с FIOSETOWN или ioctl(2) с SIOCSPGRP, то при появлении событий ввода/вывода посылается сигнал SIGIO. Для определения сокета, в котором произошло событие, в обработчике можно воспользоваться вызовом poll(2) или select(2). Альтернативным способом (в Linux 2.2) является установка сигнала реального времени с помощью вызова fcntl(2) с F_SETSIG; будет вызван обработчик сигнала реального времени и в его структуре siginfo_t поле si_fd будет содержать значение файлового дескриптора. Дополнительная информация приведена в fcntl(2).
В некоторых случаях (например, при наличии доступа нескольких процессов к одному сокету) условие, вызвавшее SIGIO, может исчезнуть на момент обработки процессом сигнала. Если это происходит, то процесс должен подождать сигнала ещё какое-то время, так как Linux снова пошлёт его позже.
Интерфейсы /proc
Вызовы ioctl
Возможные операции fcntl(2):
FIOGETOWN То же, что и вызов ioctl(2) SIOCGPGRP. FIOSETOWN То же, что и вызов ioctl(2) SIOCSPGRP.
ВЕРСИИ
ЗАМЕЧАНИЯ
В Linux разрешено повторное использование порта с параметром SO_REUSEADDR только, когда этот параметр установлен и в программе, уже выполнившей bind(2) и в программе, которая хочет использовать порт. Такое поведение отличается от некоторых реализаций (например, FreeBSD), в которых только последняя программа должна устанавливать параметр SO_REUSEADDR. Обычно, это отличие незаметно, так как, например, в серверных программах всегда устанавливают этот параметр.
Сокеты¶
Сокеты (англ. socket — разъём) — название программного интерфейса для обеспечения обмена данными между процессами. Процессы при таком обмене могут исполняться как на одной ЭВМ, так и на различных ЭВМ, связанных между собой сетью. Сокет — абстрактный объект, представляющий конечную точку соединения.
Принципы сокетов¶
Каждый процесс может создать слушающий сокет (серверный сокет) и привязать его к какому-нибудь порту операционной системы (в UNIX непривилегированные процессы не могут использовать порты меньше 1024). Слушающий процесс обычно находится в цикле ожидания, то есть просыпается при появлении нового соединения. При этом сохраняется возможность проверить наличие соединений на данный момент, установить тайм-аут для операции и т.д.
Каждый сокет имеет свой адрес. ОС семейства UNIX могут поддерживать много типов адресов, но обязательными являются INET-адрес и UNIX-адрес. Если привязать сокет к UNIX-адресу, то будет создан специальный файл (файл сокета) по заданному пути, через который смогут сообщаться любые локальные процессы путём чтения/записи из него (см. Доменный сокет Unix). Сокеты типа INET доступны из сети и требуют выделения номера порта.
Обычно клиент явно подсоединяется к слушателю, после чего любое чтение или запись через его файловый дескриптор будут передавать данные между ним и сервером.
Основные функции¶
Общие | |
Socket | Создать новый сокет и вернуть файловый дескриптор |
Send | Отправить данные по сети |
Receive | Получить данные из сети |
Close | Закрыть соединение |
Серверные | |
Bind | Связать сокет с IP-адресом и портом |
Listen | Объявить о желании принимать соединения. Слушает порт и ждет когда будет установлено соединение |
Accept | Принять запрос на установку соединения |
Клиентские | |
Connect | Установить соединение |
socket()¶
Создаёт конечную точку соединения и возвращает файловый дескриптор. Принимает три аргумента:
domain указывающий семейство протоколов создаваемого сокета
type
protocol
Протоколы обозначаются символьными константами с префиксом IPPROTO_* (например, IPPROTO_TCP или IPPROTO_UDP). Допускается значение protocol=0 (протокол не указан), в этом случае используется значение по умолчанию для данного вида соединений.
Функция возвращает −1 в случае ошибки. Иначе, она возвращает целое число, представляющее присвоенный дескриптор.
Связывает сокет с конкретным адресом. Когда сокет создается при помощи socket(), он ассоциируется с некоторым семейством адресов, но не с конкретным адресом. До того как сокет сможет принять входящие соединения, он должен быть связан с адресом. bind() принимает три аргумента:
Возвращает 0 при успехе и −1 при возникновении ошибки.
Автоматическое получение имени хоста.
listen()¶
Подготавливает привязываемый сокет к принятию входящих соединений. Данная функция применима только к типам сокетов SOCK_STREAM и SOCK_SEQPACKET. Принимает два аргумента:
После принятия соединения оно выводится из очереди. В случае успеха возвращается 0, в случае возникновения ошибки возвращается −1.
accept()¶
Используется для принятия запроса на установление соединения от удаленного хоста. Принимает следующие аргументы:
Функция возвращает дескриптор сокета, связанный с принятым соединением, или −1 в случае возникновения ошибки.
connect()¶
Устанавливает соединение с сервером.
Некоторые типы сокетов работают без установления соединения, это в основном касается UDP-сокетов. Для них соединение приобретает особое значение: цель по умолчанию для посылки и получения данных присваивается переданному адресу, позволяя использовать такие функции как send() и recv() на сокетах без установления соединения.
Загруженный сервер может отвергнуть попытку соединения, поэтому в некоторых видах программ необходимо предусмотреть повторные попытки соединения.
Возвращает целое число, представляющее код ошибки: 0 означает успешное выполнение, а −1 свидетельствует об ошибке.
Передача данных¶
Для передачи данных можно пользоваться стандартными функциями чтения/записи файлов read и write, но есть специальные функции для передачи данных через сокеты:
Нужно обратить внимание, что при использовании протокола TCP (сокеты типа SOCK_STREAM) есть вероятность получить меньше данных, чем было передано, так как ещё не все данные были переданы, поэтому нужно либо дождаться, когда функция recv возвратит 0 байт, либо выставить флаг MSG_WAITALL для функции recv, что заставит её дождаться окончания передачи. Для остальных типов сокетов флаг MSG_WAITALL ничего не меняет (например, в UDP весь пакет = целое сообщение).
Сокеты в ОС Linux
В данной статье будет рассмотрено понятие сокета в операционной системе Linux: основные структуры данных, как они работают и можно ли управлять состоянием сокета с помощью приложения. В качестве практики будут рассмотрены инструменты netcat и socat.
Что такое сокет?
Как видно по исходным кодам, все структуры достаточно объемны. Работа с ними возможна при использовании языка программирования или специальных оберток и написания приложения. Для эффективного управления этими структурами нужно знать, какие типы операций над сокетами существуют и когда их применять. Для сокетов существует набор стандартных действий:
Если о структурах, которые описаны выше, заботится ядро операционной системы, то в случае команд по управлению соединением ответственность берет на себя приложение, которое хочет пересылать данные по сети. Попробуем использовать знания о сокетах для работы с приложениями netcat и socat.
netcat
Оригинальная утилита появилась 25 лет назад, больше не поддерживается. На cегодняшний день существуют порты, которые поддерживаются различными дистрибутивами: Debian, Ubuntu, FreeBSD, MacOS. В операционной системе утилиту можно вызвать с помощью команды nc, nc.traditional или ncat в зависимости от ОС. Утилита позволяет «из коробки» работать с сокетами, которые используют в качестве транспорта TCP и UDP протоколы. Примеры сценариев использования, которые, по мнению автора, наиболее интересны:
перенаправление входящих/исходящих запросов;
трансляция данных на экран в шестнадцатеричном формате.
Опробуем операции в действии. Задача будет состоять в том, что необходимо отправить TCP данные через netcat в UDP соединение. Для лабораторной будет использоваться следующая топология сети:
В итоге получаем возможность читать данные от машины Source:
В машине Destination:
Пример с трансляцией данных в шестнадцатеричном формате можно провести так же, но заменить команду на Destination или добавить еще один пайп на Repeater:
В результате будет создан файл, в котором можно будет обнаружить передаваемые данные в шестнадцатеричном формате:
Как видно из тестового сценария использования, netcat не дает контролировать практически ничего, кроме направления данных. Нет ни разграничения доступа к ресурсам, которые пересылаются, ни возможности без дополнительных ухищрений работать с двумя сокетами, ни возможности контролировать действия сокета. Протестируем socat.
socat
Инструмент, который до сих пор поддерживается и имеет весьма обширный функционал по склейке каналов для взаимодействия. Разработчиками инструмент именуется как netcat++. Ниже приведем небольшой список того что можно перенаправить через socat:
Для повседневного использования достаточно опций, но если понадобится когда-то работать напрямую с серийным портом или виртуальным терминалом, то socat тоже умеет это делать. Полный перечень опций можно вызвать с помощью команды:
Помимо редиректов socat также можно использовать как универсальный сервер для расшаривания ресурсов, через него можно как через chroot ограничивать привилегии и доступ к директориям системы.
Чтобы комфортно пользоваться этим инструментом, нужно запомнить шаблон командной строки, который ожидает socat:
socat additionalOptions addr1 addr2
Попробуем провести трансляцию данных из сокета в сокет. Будем использовать для этого 1 машину. Перед началом эксперимента стоит отметить, что особенностью socat является то, что для его корректной работы нужно обязательно писать 2 адреса. Причем адрес не обязательно должен быть адресом, это может быть и приложение, и стандартный вывод на экран.
Например, чтобы использовать socat как netcat в качестве TCP сервера, можно запустить вот такую команду:
socat TCP-LISTEN:4545, STDOUT
Для коннекта можно использовать netcat:
При таком использовании, socat дает возможность пересылать сообщения в обе стороны, но если добавить флаг «-u», то общение будет только от клиента к серверу. Все серверные сообшения пересылаться не будут:
Настроим более тонко наш сервер, добавив новые опции через запятую после используемого действия:
socat TCP-LISTEN:4545,reuseaddr,keepalive,fork STDOUT
Дополнительные параметры распространяются на те действия, которые socat может выполнять по отношению к адресу. Полный список опций можно найти здесь в разделе «SOCKET option group».
Таким образом socat дает практически полный контроль над состоянием сокетов и расшариваемых ресурсов.
Статья написана в преддверии старта курса Network engineer. Basic. Всех, кто желает подробнее узнать о курсе и карьерных перспективах, приглашаем записаться на день открытых дверей, который пройдет уже 4 февраля.