Функции Perl для работы с сокетами

Небольшая заметка. Что такое сокет. Функции accept, bind, connect, getpeername, getsockname, getsockopt, listen, recv, send, setsockopt, shutdown, socket, socketpair. Простые примеры кода сервера и клиента.

 

Что такое сокет. Краткое описание логики работы сокета

Сокеты Беркли — это API, библиотека для разработки приложений на языке Си, которая позволяет организовать межсетевое взаимодействие.

Альтернативой сокетам Беркли, является API TLI (Transport Level Interface), основанный на STREAMS.

Базовые операции сокетов для TCP: SOCKET, BIND, LISTEN, ACCEPT, SEND, RECEIVE, CLOSE.

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

Только что созданный сокет не связан ни с какими сетевыми адресами. Сетевой адрес назначается с помощью операции BIND.

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

ACCEPT - пассивное установление соединения. В противоположность ему, могут использоваться активные попытки установить соединение - операция CONNECT. Т.е. разница в том, кто именно инициирует попытки установить связь. После того, как с помощью ACCEPT был получен запрос на соединение, транспортная подсистема создает новый сокет с теми же параметрами, как у исходного, и возвращает дескриптор файла для него. На этом этапе, для обработки поступившего запроса, может быть создан дочерний процесс, который займется обработкой, в то время как исходный сокет вернется к прослушиванию порта и ожиданию новых запросов.

Для отправки и получения данных между клиентом и сервером, после установления соединения, можно использовать операции SEND и RECEIVE. В модели сокетов используется симметричный разрыв соединения, т.е. соединение будет разорвано после того, как обе стороны выполнят операцию CLOSE.

 

Функции Perl для работы с сокетами

socket

Функция создает сокет заданного типа и связывает его с файловым дескриптором SOCKET. До того, как будет позвана функция socket(), необходимо подключить модуль Socket:

Этот модуль поставляет необходимые для работы с сокетами константы. Функция возвращает значение true в случае успешного выполнения.

DOMAIN выбирает семейство протоколов, которые будут использоваться сокетом для создания соединения:

  • PF_INET для сетевого протокола IPv4 или
  • PF_INET6 для IPv6.
  • PF_UNIX (PF_LOCAL) для локальных сокетов (используя файл).

TYPE один из:

  • SOCK_STREAM - Надёжная потокоориентированная служба (сервис) или потоковый сокет. Обеспечивает создание двусторонних надежных и последовательных потоков байтов , поддерживающих соединения. Может также поддерживаться механизм внепоточных данных.
  • SOCK_DGRAM - Датаграммный сокет, ненадежные сообщения с ограниченной длиной и не поддерживающие соединения.
  • SOCK_RAW - Обеспечивает доступ к низкоуровневому сетевому протоколу. Perl поддерживает работу с SOCK_RAW, при подключении дополнительных модулей.

Параметр PROTOCOL задает конкретный протокол, который работает с сокетом.

socketpair

Эта функция создает пару сокетов заданного типа, в заданном домене. Функция возвращает true, в случае успеха и false - если выполнение по тем или иным причинам завершилось неудачно. В системах, где не реализован socketpair(2), вызов этой функции приведет к возникновению исключительной ситуации.

Обычно эта функция вызывается непосредственно перед fork().

bind

Функция bind связывает заранее известный порт и ip-адрес сервера с созданным сокетом. Функция возвращает true в случае успеха, или false - в противном случае.

NAME - это специальным образом упакованная структура, которая содержит ip-адрес и порт сервера.

listen

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

Функция возвращает значение true, в случае успеха, и false - в противном случае.

accept

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

Для каждого клиента будет заводиться новый дескриптор.

recv

Функция получает сообщение на сокет. Пытается получить LENGHT байт в переменную SCALAR из заданного файлового дескриптора SOCKET. Функция возвращает адрес отправителя или undef, в случае ошибки.

send

Функция посылает сообщение на сокет.

shutdown

Функция закрывает соединение с сокетом. Если HOW имеет значение
0 - дальнейший прием данных запрещен,
1 - запрещена дальнейшая отправка данных,
2 - запрещены и прием, и отправка данных.

Функция используется, когда неободимо сообщить другой стороне, что закончена запись, но еще не закончено чтение, или наоборот.

Функция отключает копии дескрипторов соединения в дочерних процессах.

close

Функция закрывает сокет. Возвращает значение true, если закрытие прошло успешно,
и false - в противном случае.

getpeername

Функция возвращает упакованный адрес сокета противоположного конца соединения SOCKET.

getsockname

Функция возвращает упакованный адрес сокета данного конца соединения SOCKET. Это может пригодиться, если дескриптор сокета был передан нам от родительского процесса, и мы не знаем исходных параметров создания сокета. Или в иных, подобных случаях.

getsockopt

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

setsockopt

Функция устанавливает требуемые параметры сокета. Возвращает undef в случае ошибки.
LEVEL - обозначает уровень протокола, на который нацелен вызов. Можно указать SOL_SOCKET, если параметры задаются для самого сокета, поверх всех уровней.

 

Функции модуля Socket.pm

inet_aton

Функция inet_aton выполняет преобразование ip-адреса из обычной строки в упакованный бинарный формат. Если преобразование выполнить не удалось, функция вернет undef. Работает только с адресами типа IPv4.

inet_ntoa

Функция inet_ntoa - выполняет обратное inet_aton преобразование. Принимает на вход упакованный адрес, возвращает i-адрес в виде обычной ascii-строки. Только для адресов IPv4.

inet_pton

Принимает на вход название семейства адресов (например, PF_INET6), строку с адресом и возвращает указанный адрес в упакованном бинарном виде. Т.е. альтернатива inet_aton, с большими возможностями.

inet_ntop

Функция принимает на вход - название семейства, к которому принадлежит адрес, ссылку на упакованный адрес и возвращает ip-адрес в виде обычной строки. Функция является более современной альтернативой inet_ntoa.

pack_sockaddr_in

Функция принимает на вход два аргумента, номер порта и уже упакованный с помощью inet_aton, ip-адрес сервера. Возвращает упакованную структуру, которую в дальнейшем используют в командах bind, connect и send.

 

Пример работы с сокетами 1

Код сервера:

Код клиента:

При обращении клиента, сервер вывел в STDOUT:

Результат работы клиента:

 

Пример работы с сокетами 2

Создание клиента и сервера, работа с сокетами, использование модуля IO::Socket::INET.

Программный код сервера:

Сервер доступен по адресу: http://195.50.224.234:3002/ Для обращения к нему можно использовать браузер.

При обращении через браузер, сервер выдает в STDOUT:

Код клиента:

При запуске клиента, сервер выведет в STDOUT:

Клиент в свою очередь выведет:

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

Shutdown(SOCKET, 1) в примере используется, чтобы, не закрывая сокет, сообщить системе на другом конце соединения, о завершении передачи данных.

Используем netstat для получения информации о текущем состоянии нашей системы:

После того, как был запущен сервер, значения netstat изменились:

Узнаем номер процесса сервера:

В списке файлов, открытых процессом сервера, появилась строка с информацией о сокете:

 

Полезные ссылки по теме сокетов

search.cpan.org: Socket

Функции Perl для работы с сокетами: 2 комментария

  1. afiskon

    Годная заметка, спасибо :) Было бы интересно почитать как сейчас обстоят дела с многопоточностью в Perl, а то я в этой теме отстал немного. fork() вроде все так же рулит, трэды задепрекейтили, нового ничего не появилось?

  2. Andrey

    Здорово. А можно еще статью про работу с INET-сокетами в неблокирующем режиме?

Комментарии запрещены.