Сокет
СОДЕРЖАНИЕ
- ИМЯ
- СИНОПСИС
- ОПИСАНИЕ
- КОНСТАНТЫ
- 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 неизвестного типа.
$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() (или v-строку, представляющую четыре октета IPv4-адреса в сетевом порядке), и преобразует её в строку вида d.d.d.d, где d - числа меньше 256 (обычный человекочитаемый четырехточечный числовой формат для адресов Интернета).
Эта функция, предназначенная только для 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]
При заданном имени хоста и имени службы эта функция пытается разрешить имя хоста в список сетевых адресов и имя службы в протокол и номер порта, а затем возвращает список структур адресов, пригодных для подключения к нему.
Если задано только имя хоста, эта функция пытается разрешить его в список сетевых адресов и затем возвращает список структур адресов, содержащих эти адреса.
Если задано только имя службы, эта функция пытается разрешить его в протокол и номер порта, а затем возвращает список структур адресов, которые представляют его, пригодные для связывания с помощью функции bind(). Это использование должно быть комбинировано с флагом 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 разработчиками Perl 5.
Он был выделен в двойной жизни на 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.34.0/Socket