Сокет
СОДЕРЖАНИЕ
- НАЗВАНИЕ
- СИНТАКСИС
- ОПИСАНИЕ
- КОНСТАНТЫ
- 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
- ФУНКЦИИ
- КОНСТАНТЫ ОШИБОК getaddrinfo() / getnameinfo()
- ПРИМЕРЫ
- АВТОР
НАЗВАНИЕ
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