Spec-Zone.ru › Perl 5.36

Сокет

СОДЕРЖАНИЕ

  • НАЗВАНИЕ
  • СИНТАКСИС
  • ОПИСАНИЕ
  • КОНСТАНТЫ
    • 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 = 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 sockopts.

($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 sockopts.

($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 sockopts.

($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() (или строку-объект, представляющую четыре октета 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

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

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() преобразует имя хоста и имя службы в список структур, каждая из которых содержит потенциальный способ подключения() к указанной службе на указанном хосте.

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–2021 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.36.0/Socket

Spec-Zone.ru

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