Spec-Zone.ru › Perl 5.38

Сокет

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНТАКСИС
  • ОПИСАНИЕ
  • КОНСТАНТЫ
    • PF_INET, PF_INET6, PF_UNIX, ...
    • AF_INET, AF_INET6, AF_UNIX, ...
    • SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, ...
    • SOCK_NONBLOCK. SOCK_CLOEXEC
    • SOL_SOCKET
    • SO_ACCEPTCONN, SO_BROADCAST, SO_ERROR, ...
    • IP_OPTIONS, IP_TOS, IP_TTL, ...
    • IP_PMTUDISC_WANT, IP_PMTUDISC_DONT, ...
    • IPTOS_LOWDELAY, IPTOS_THROUGHPUT, IPTOS_RELIABILITY, ...
    • MSG_BCAST, MSG_OOB, MSG_TRUNC, ...
    • SHUT_RD, SHUT_RDWR, SHUT_WR
    • INADDR_ANY, INADDR_BROADCAST, INADDR_LOOPBACK, INADDR_NONE
    • IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP, ...
    • TCP_CORK, TCP_KEEPALIVE, TCP_NODELAY, ...
    • IN6ADDR_ANY, IN6ADDR_LOOPBACK
    • IPV6_ADD_MEMBERSHIP, IPV6_MTU, IPV6_V6ONLY, ...
  • МАНИПУЛЯТОРЫ СТРУКТУР
    • $family = sockaddr_family $sockaddr
    • $sockaddr = pack_sockaddr_in $port, $ip_address
    • ($port, $ip_address) = unpack_sockaddr_in $sockaddr
    • $sockaddr = sockaddr_in $port, $ip_address
    • ($port, $ip_address) = sockaddr_in $sockaddr
    • $sockaddr = pack_sockaddr_in6 $port, $ip6_address, [$scope_id, [$flowinfo]]
    • ($port, $ip6_address, $scope_id, $flowinfo) = unpack_sockaddr_in6 $sockaddr
    • $sockaddr = sockaddr_in6 $port, $ip6_address, [$scope_id, [$flowinfo]]
    • ($port, $ip6_address, $scope_id, $flowinfo) = sockaddr_in6 $sockaddr
    • $sockaddr = pack_sockaddr_un $path
    • ($path) = unpack_sockaddr_un $sockaddr
    • $sockaddr = sockaddr_un $path
    • ($path) = sockaddr_un $sockaddr
    • $ip_mreq = pack_ip_mreq $multiaddr, $interface
    • ($multiaddr, $interface) = unpack_ip_mreq $ip_mreq
    • $ip_mreq_source = pack_ip_mreq_source $multiaddr, $source, $interface
    • ($multiaddr, $source, $interface) = unpack_ip_mreq_source $ip_mreq
    • $ipv6_mreq = pack_ipv6_mreq $multiaddr6, $ifindex
    • ($multiaddr6, $ifindex) = unpack_ipv6_mreq $ipv6_mreq
  • ФУНКЦИИ
    • $ip_address = inet_aton $string
    • $string = inet_ntoa $ip_address
    • $address = inet_pton $family, $string
    • $string = inet_ntop $family, $address
    • ($err, @result) = getaddrinfo $host, $service, [$hints]
    • ($err, $hostname, $servicename) = getnameinfo $sockaddr, [$flags, [$xflags]]
  • КОНСТАНТЫ ОШИБОК getaddrinfo() / getnameinfo()
  • ПРИМЕРЫ
    • Поиск для connect()
    • Преобразование адреса в удобочитаемую строку
    • Разрешение имён хостов в IP-адреса
    • Доступ к параметрам сокета
  • АВТОР

ИМЯ

Socket - сетевые константы и вспомогательные функции

СИНТАКСИС

Socket низкоуровневый модуль, используемый, среди прочего, семейством модулей IO::Socket. Следующие примеры демонстрируют некоторые низкоуровневые использования, но практическая программа, скорее всего, будет использовать более высокий уровень API, предоставляемый IO::Socket или подобным.

use Socket qw(PF_INET SOCK_STREAM pack_sockaddr_in inet_aton);

socket(my $socket, PF_INET, SOCK_STREAM, 0)
    or die "socket: $!";

my $port = getservbyname "echo", "tcp";
connect($socket, pack_sockaddr_in($port, inet_aton("localhost")))
    or die "connect: $!";

print $socket "Hello, world!\n";
print <$socket>;

См. также раздел "ПРИМЕРЫ".

ОПИСАНИЕ

Этот модуль предоставляет различные константы, манипуляторы структур и другие функции, связанные с сетевыми соединениями через сокеты. Значения и функции полезны при совместном использовании с функциями ядра Perl, такими как socket(), setsockopt() и bind(). Он также предоставляет несколько других вспомогательных функций, в основном для преобразования сетевых адресов между удобочитаемыми и внутренними двоичными форматами, а также для операций разрешения имён хостов.

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

Также предоставлены некоторые общие константы сетевых "переносов строки": константы CR, LF, и CRLF, а также $CR, $LF, и $CRLF, которые соответствуют \015, \012, и \015\012. Если вы не хотите использовать буквальные символы в своих программах, используйте предоставленные здесь константы. Они не экспортируются по умолчанию, но могут быть импортированы индивидуально, и с тегом экспорта :crlf:

use Socket qw(:DEFAULT :crlf);

$sock->print("GET / HTTP/1.0$CRLF");

Всю подсистему getaddrinfo() можно экспортировать с помощью тега :addrinfo; это экспортирует функции getaddrinfo() и getnameinfo(), а также все константы AI_*, NI_*, NIx_* и EAI_*.

КОНСТАНТЫ

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

PF_INET, PF_INET6, PF_UNIX, ...

Константы семейства протоколов для использования в качестве первого аргумента socket() или значения параметра сокета SO_DOMAIN или SO_FAMILY.

AF_INET, AF_INET6, AF_UNIX, ...

Константы семейства адресов, используемые структурами адресов сокета, для передачи в такие функции, как inet_pton() или getaddrinfo(), или возвращаемые такими функциями, как sockaddr_family().

SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, ...

Константы типа сокета для использования в качестве второго аргумента socket() или значения параметра сокета SO_TYPE.

SOCK_NONBLOCK. SOCK_CLOEXEC

Конкретные для Linux сокращения для указания флагов O_NONBLOCK и FD_CLOEXEC во время вызова socket(2).

socket( my $sockh, PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, 0 )

SOL_SOCKET

Константа уровня параметра сокета для setsockopt() и getsockopt().

SO_ACCEPTCONN, SO_BROADCAST, SO_ERROR, ...

Константы имён параметров сокета для setsockopt() и getsockopt() на уровне SOL_SOCKET.

IP_OPTIONS, IP_TOS, IP_TTL, ...

Константы имён параметров сокета для параметров сокета IPv4 на уровне IPPROTO_IP.

IP_PMTUDISC_WANT, IP_PMTUDISC_DONT, ...

Константы значений параметров сокета для параметра сокета IP_MTU_DISCOVER.

IPTOS_LOWDELAY, IPTOS_THROUGHPUT, IPTOS_RELIABILITY, ...

Константы значений параметров сокета для параметра сокета IP_TOS.

MSG_BCAST, MSG_OOB, MSG_TRUNC, ...

Константы флагов сообщений для send() и recv().

SHUT_RD, SHUT_RDWR, SHUT_WR

Константы направления для shutdown().

INADDR_ANY, INADDR_BROADCAST, INADDR_LOOPBACK, INADDR_NONE

Константы, задающие специальные AF_INET адреса для маски, широковещательного, локального обратного соединения и недействительного адресов.

Обычно эквивалентны inet_aton('0.0.0.0'), inet_aton('255.255.255.255'), inet_aton('localhost') и inet_aton('255.255.255.255') соответственно.

IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP, ...

Константы протоколов IP для использования в качестве третьего аргумента socket(), аргумента уровня getsockopt() или setsockopt(), или значения SO_PROTOCOL параметра сокета.

TCP_CORK, TCP_KEEPALIVE, TCP_NODELAY, ...

Константы имён параметров сокета для параметров сокета TCP на уровне IPPROTO_TCP.

IN6ADDR_ANY, IN6ADDR_LOOPBACK

Константы, задающие специальные AF_INET6 адреса для маски и локального обратного соединения.

Обычно эквивалентны inet_pton(AF_INET6, "::") и inet_pton(AF_INET6, "::1") соответственно.

IPV6_ADD_MEMBERSHIP, IPV6_MTU, IPV6_V6ONLY, ...

Константы имён параметров сокета для параметров сокета IPv6 на уровне IPPROTO_IPV6.

СТРУКТУРНЫЕ МОДИФИКАТОРЫ

Следующие функции преобразуют списки значений Perl в упакованные двоичные строки, представляющие структуры.

$family = sockaddr_family $sockaddr

Принимает упакованный адрес сокета (как возвращается pack_sockaddr_in(), pack_sockaddr_un() или встроенными функциями Perl getsockname() и getpeername()). Возвращает тег семейства адресов. Это будет одна из AF_* констант, таких как AF_INET для sockaddr_in адресов или AF_UNIX для sockaddr_un. Можно использовать для определения, какой unpack следует использовать для sockaddr неизвестного типа.

$sockaddr = pack_sockaddr_in $port, $ip_address

Принимает два аргумента: номер порта и строку (как возвращается inet_aton() или v-строка). Возвращает структуру sockaddr_in с упакованными аргументами и заполненным AF_INET. Для сокетов доменной сети эта структура обычно необходима в качестве аргументов в bind(), connect() и send().

Неопределённый аргумент $port принимается как ноль; неопределённый $ip_address считается ошибкой.

($port, $ip_address) = unpack_sockaddr_in $sockaddr

Принимает структуру sockaddr_in (как возвращается pack_sockaddr_in(), getpeername() или recv()). Возвращает список из двух элементов: номер порта и строку, представляющую IP-адрес (можно использовать inet_ntoa() для преобразования адреса в формат четырёх точек с числовыми значениями). Возвращает ошибку, если структура не представляет AF_INET адрес.

В скалярном контексте возвращает только IP-адрес.

$sockaddr = sockaddr_in $port, $ip_address

($port, $ip_address) = sockaddr_in $sockaddr

Обёртка для pack_sockaddr_in() или unpack_sockaddr_in(). В контексте списка распаковывает аргумент и возвращает список, состоящий из номера порта и IP-адреса. В скалярном контексте упаковывает аргументы номера порта и IP-адреса в sockaddr_in и возвращает его.

Предоставляется в основном для обеспечения совместимости со старыми версиями; лучше использовать pack_sockaddr_in() или unpack_sockaddr_in() явно.

$sockaddr = pack_sockaddr_in6 $port, $ip6_address, [$scope_id, [$flowinfo]]

Принимает от двух до четырёх аргументов: номер порта, строку (как возвращается inet_pton()), необязательно номер идентификатора области видимости и необязательно номер метки потока. Возвращает структуру sockaddr_in6 с упакованными аргументами и заполненным AF_INET6. IPv6 эквивалент pack_sockaddr_in().

Неопределённый аргумент $port принимается как ноль; неопределённый $ip6_address считается ошибкой.

($port, $ip6_address, $scope_id, $flowinfo) = unpack_sockaddr_in6 $sockaddr

Принимает структуру sockaddr_in6. Возвращает список из четырёх элементов: номер порта, строку, представляющую IPv6-адрес, идентификатор области видимости и метку потока. (Можно использовать inet_ntop() для преобразования адреса в обычный строковый формат). Возвращает ошибку, если структура не представляет AF_INET6 адрес.

В скалярном контексте возвращает только IP-адрес.

$sockaddr = sockaddr_in6 $port, $ip6_address, [$scope_id, [$flowinfo]]

($port, $ip6_address, $scope_id, $flowinfo) = sockaddr_in6 $sockaddr

Обёртка для pack_sockaddr_in6() или unpack_sockaddr_in6(). В контексте списка распаковывает аргумент согласно unpack_sockaddr_in6(). В скалярном контексте упаковывает аргументы согласно pack_sockaddr_in6().

Предоставляется в основном для обеспечения совместимости со старыми версиями; лучше использовать pack_sockaddr_in6() или unpack_sockaddr_in6() явно.

$sockaddr = pack_sockaddr_un $path

Принимает один аргумент: имя пути. Возвращает структуру sockaddr_un с упакованным путем и заполненным AF_UNIX. Для PF_UNIX сокетов эта структура обычно необходима в качестве аргументов в bind(), connect() и send().

($path) = unpack_sockaddr_un $sockaddr

Принимает структуру sockaddr_un (как возвращается pack_sockaddr_un(), getpeername() или recv()). Возвращает список из одного элемента: путь. Возвращает ошибку, если структура не представляет AF_UNIX адрес.

$sockaddr = sockaddr_un $path

($path) = sockaddr_un $sockaddr

Обёртка для pack_sockaddr_un() или unpack_sockaddr_un(). В контексте списка распаковывает аргумент и возвращает список, содержащий путь. В скалярном контексте упаковывает свой аргумент пути в sockaddr_un и возвращает его.

Предоставляется в основном для обеспечения совместимости со старыми версиями; лучше использовать pack_sockaddr_un() или unpack_sockaddr_un() явно.

Эти функции поддерживаются только если на вашем компьютере есть <sys/un.h>.

$ip_mreq = pack_ip_mreq $multiaddr, $interface

Принимает IPv4 многоадресного адреса и, необязательно, адрес интерфейса (или INADDR_ANY). Возвращает структуру ip_mreq с упакованными аргументами. Подходит для использования с IP_ADD_MEMBERSHIP и IP_DROP_MEMBERSHIP параметрами сокета.

($multiaddr, $interface) = unpack_ip_mreq $ip_mreq

Принимает структуру ip_mreq. Возвращает список из двух элементов: IPv4 многоадресного адреса и адреса интерфейса.

$ip_mreq_source = pack_ip_mreq_source $multiaddr, $source, $interface

Принимает IPv4 многоадресного адреса, адрес источника и, необязательно, адрес интерфейса (или INADDR_ANY). Возвращает структуру ip_mreq_source с упакованными аргументами. Подходит для использования с IP_ADD_SOURCE_MEMBERSHIP и IP_DROP_SOURCE_MEMBERSHIP параметрами сокета.

($multiaddr, $source, $interface) = unpack_ip_mreq_source $ip_mreq

Принимает структуру ip_mreq_source. Возвращает список из трёх элементов: IPv4 многоадресного адреса, адреса источника и адреса интерфейса.

$ipv6_mreq = pack_ipv6_mreq $multiaddr6, $ifindex

Принимает IPv6 многоадресного адреса и номер интерфейса. Возвращает структуру ipv6_mreq с упакованными аргументами. Подходит для использования с IPV6_ADD_MEMBERSHIP и IPV6_DROP_MEMBERSHIP параметрами сокета.

($multiaddr6, $ifindex) = unpack_ipv6_mreq $ipv6_mreq

Принимает структуру ipv6_mreq. Возвращает список из двух элементов: IPv6 адреса и номера интерфейса.

ФУНКЦИИ

$ip_address = inet_aton $string

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

Для портативности не предполагайте, что результат inet_aton() имеет 32 бита ширины, то есть что он будет содержать только IPv4-адрес в сетевом порядке.

Эта функция, предназначенная только для IPv4, предоставляется в основном по причинам совместимости со старыми версиями. В новых кодах следует использовать getaddrinfo() или inet_pton() для поддержки IPv6.

$string = inet_ntoa $ip_address

Принимает упакованную двоичную структуру адреса, такую как возвращаемая unpack_sockaddr_in() (или v-строку, представляющую четыре октета IPv4-адреса в сетевом порядке), и преобразует её в строку формата d.d.d.d, где d — числа меньше 256 (обычное человекочитаемое представление IP-адреса в виде четырёх точек с числовыми значениями).

Эта функция, предназначенная только для IPv4, предоставляется в основном по причинам совместимости со старыми версиями. В новых кодах следует использовать getnameinfo() или inet_ntop() для поддержки IPv6.

$address = inet_pton $family, $string

Принимает семейство адресов (например, AF_INET или AF_INET6) и строку, содержащую текстовое представление адреса в этом семействе, и преобразует её в упакованную двоичную структуру адреса.

См. также getaddrinfo() для более мощной и гибкой функции поиска адресов сокетов по именам хостов или текстовым адресам.

$string = inet_ntop $family, $address

Принимает семейство адресов и упакованную двоичную структуру адреса и преобразует её в удобочитаемое текстовое представление адреса; обычно в формате d.d.d.d для AF_INET или hhhh:hhhh::hhhh для AF_INET6.

См. также getnameinfo() для более мощной и гибкой функции преобразования адресов сокетов в удобочитаемые текстовые представления.

($err, @result) = getaddrinfo $host, $service, [$hints]

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

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

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

Если ни одно имя не указано, генерируется ошибка.

Если присутствует $hints, он должен быть ссылкой на хеш, где распознаются следующие ключи:

flags => INT

Битовое поле, содержащее AI_* константы; см. ниже.

family => INT

Ограничить генерацию адресов только этой семейством адресов

socktype => INT

Ограничить генерацию адресов только этого типа сокета

protocol => INT

Ограничить генерацию адресов только для этого протокола

Значение результата будет списком; первым значением будет индикатор ошибки, за которым следует список структур адресов (если ошибки не произошло).

Значение ошибки будет двойным значением; сравнимым с EAI_* константами ошибок, или выводимым в виде читаемой человеком строки сообщения об ошибке. Если ошибки не произошло, оно будет численно равно нулю и пустой строкой.

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

family => INT

Семейство адресов (например, AF_INET)

socktype => INT

Тип сокета (например, SOCK_STREAM)

protocol => INT

Протокол (например, IPPROTO_TCP)

addr => STRING

Адрес в упакованной строке (такой, как возвращаемый pack_sockaddr_in())

canonname => STRING

Каноническое имя хоста, если был передан AI_CANONNAME флаг, или undef в противном случае. Это поле будет присутствовать только в первом возвращенном адресе.

В хэше $hints распознаются следующие флаги констант. Другие константы флагов могут существовать, как предоставленные ОС.

AI_PASSIVE

Указывает, что это разрешение предназначено для локального bind() для пассивного (т.е. прослушивающего) сокета, а не для активного (т.е. подключающегося) сокета.

AI_CANONNAME

Указывает, что вызывающий хочет, чтобы поле канонического имени хоста (canonname) результата было заполнено.

AI_NUMERICHOST

Указывает, что вызывающий передаст числовой адрес, а не имя хоста, и что getaddrinfo() не должен выполнять операцию разрешения по этому имени. Этот флаг предотвратит, возможно, медленную сетевую операцию поиска, а вместо этого вернет ошибку, если передано имя хоста.

($err, $hostname, $servicename) = getnameinfo $sockaddr, [$flags, [$xflags]]

Принимая упакованный адрес сокета (например, из getsockname(), getpeername() или возвращаемый getaddrinfo() в addr поле), возвращает имя хоста и символическое имя службы, которые он представляет. $flags может быть битовой маской NI_* констант или по умолчанию 0, если не указано.

Значение результата будет списком; первым значением будет состояние ошибки, за которым следуют имя хоста и имя службы.

Значение ошибки будет двойным значением; сравнимым с EAI_* константами ошибок, или выводимым в виде читаемой человеком строки сообщения об ошибке. Имена хоста и службы будут обычными строками.

Следующие флаги констант распознаются как $flags. Другие константы флагов могут существовать, как предоставленные ОС.

NI_NUMERICHOST

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

NI_NUMERICSERV

Запрашивает, чтобы номер порта возвращался непосредственно как числовое представление, а не выполнялась операция разрешения имени, которая может преобразовать его в имя службы.

NI_NAMEREQD

Если операция разрешения имени завершается неудачей, то этот флаг заставит getnameinfo() указать ошибку, а не возвращать числовое представление в виде удобочитаемой строки.

NI_DGRAM

Указывает, что адрес сокета относится к сокету SOCK_DGRAM, для служб, имена которых отличаются в протоколах TCP и UDP.

Следующие константы могут быть переданы как $xflags.

NIx_NOHOST

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

NIx_NOSERV

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

getaddrinfo() / getnameinfo() константы ошибок

Следующие константы могут быть возвращены getaddrinfo() или getnameinfo(). Другие могут быть предоставлены ОС.

EAI_AGAIN

Во время разрешения имен произошла временная ошибка. Операция может быть успешной, если повторить ее позже.

EAI_BADFLAGS

Значение flags подсказки для getaddrinfo() или параметр $flags для getnameinfo() содержит неизвестные флаги.

EAI_FAMILY

family подсказка для getaddrinfo(), или семейство адреса сокета, переданного getnameinfo(), не поддерживается.

EAI_NODATA

Переданное имя хоста getaddrinfo() не предоставило никаких полезных данных адреса.

EAI_NONAME

Переданное имя хоста getaddrinfo() не существует, или переданный адрес getnameinfo() не связан с именем хоста, и был передан NI_NAMEREQD флаг.

EAI_SERVICE

Переданное имя службы getaddrinfo() недоступно для типа сокета, указанного в $hints.

ПРИМЕРЫ

Поиск для connect()

Функция getaddrinfo() преобразует имя хоста и имя службы в список структур, каждая из которых содержит потенциальный способ подключения connect() к указанной службе на указанном хосте.

use IO::Socket;
use Socket qw(SOCK_STREAM getaddrinfo);

my %hints = (socktype => SOCK_STREAM);
my ($err, @res) = getaddrinfo("localhost", "echo", \%hints);
die "Cannot getaddrinfo - $err" if $err;

my $sock;

foreach my $ai (@res) {
    my $candidate = IO::Socket->new();

    $candidate->socket($ai->{family}, $ai->{socktype}, $ai->{protocol})
        or next;

    $candidate->connect($ai->{addr})
        or next;

    $sock = $candidate;
    last;
}

die "Cannot connect to localhost:echo" unless $sock;

$sock->print("Hello, world!\n");
print <$sock>;

Поскольку возвращается список потенциальных кандидатов, цикл while пытается подключиться к каждому по очереди, пока не найдет такой, который успешно пройдет вызовы socket() и connect().

Эта функция выполняет работу устаревших функций gethostbyname(), getservbyname(), inet_aton() и pack_sockaddr_in().

На практике эта логика лучше выполняется с помощью IO::Socket::IP.

Преобразование адреса в удобочитаемую строку

Функция getnameinfo() преобразует адрес сокета, например, возвращенный getsockname() или getpeername(), в пару удобочитаемых строк, представляющих адрес и имя службы.

use IO::Socket::IP;
use Socket qw(getnameinfo);

my $server = IO::Socket::IP->new(LocalPort => 12345, Listen => 1) or
    die "Cannot listen - $@";

my $socket = $server->accept or die "accept: $!";

my ($err, $hostname, $servicename) = getnameinfo($socket->peername);
die "Cannot getnameinfo - $err" if $err;

print "The peer is connected from $hostname\n";

Так как в этом примере использовалось только имя хоста, избыточное преобразование номера порта в имя службы может быть опущено путем передачи NIx_NOSERV флага.

use Socket qw(getnameinfo NIx_NOSERV);

my ($err, $hostname) = getnameinfo($socket->peername, 0, NIx_NOSERV);

Эта функция выполняет работу устаревших функций unpack_sockaddr_in(), inet_ntoa(), gethostbyaddr() и getservbyport().

На практике эта логика лучше выполняется с помощью IO::Socket::IP.

Разрешение имен хостов в IP-адреса

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

use Socket qw(:addrinfo SOCK_RAW);

my ($err, @res) = getaddrinfo($hostname, "", {socktype => SOCK_RAW});
die "Cannot getaddrinfo - $err" if $err;

while( my $ai = shift @res ) {
    my ($err, $ipaddr) = getnameinfo($ai->{addr}, NI_NUMERICHOST, NIx_NOSERV);
    die "Cannot getnameinfo - $err" if $err;

    print "$ipaddr\n";
}

socktype подсказка для getaddrinfo() фильтрует результаты, чтобы включить только один тип сокета и протокол. Без этого большинство ОС возвращают три комбинации для SOCK_STREAM, SOCK_DGRAM и SOCK_RAW, что приводит к тройному выводу адресов. NI_NUMERICHOST флаг для getnameinfo() заставляет его возвращать строковое представление чистого IP-адреса, а не обратное разрешение обратно в имя хоста.

Эта комбинация выполняет работу устаревших функций gethostbyname() и inet_ntoa().

Доступ к параметрам сокета

Многие SO_* и другие константы предоставляют имена параметров сокета для getsockopt() и setsockopt().

use IO::Socket::INET;
use Socket qw(SOL_SOCKET SO_RCVBUF IPPROTO_IP IP_TTL);

my $socket = IO::Socket::INET->new(LocalPort => 0, Proto => 'udp')
    or die "Cannot create socket: $@";

$socket->setsockopt(SOL_SOCKET, SO_RCVBUF, 64*1024) or
    die "setsockopt: $!";

print "Receive buffer is ", $socket->getsockopt(SOL_SOCKET, SO_RCVBUF),
    " bytes\n";

print "IP TTL is ", $socket->getsockopt(IPPROTO_IP, IP_TTL), "\n";

Для удобства метод setsockopt() IO::Socket преобразует число в упакованный байтовый буфер, а getsockopt() распакует байтовый буфер нужного размера обратно в число.

АВТОР

Этот модуль изначально поддерживался ядром Perl 5 разработчиками Perl.

Он был извлечен на CPAN в версии 1.95 Павлом Эвансом <leonerd@leonerd.org.uk>

© 1993–2023 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.38.0/Socket

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API