IO::Socket::IP - Use IPv4 and IPv6 sockets in a protocol-independent way
IO::Socket::IP
use IO::Socket::IP; my $sock = IO::Socket::IP->new( PeerHost => "www.google.com", PeerService => "www", ) or die "Cannot construct socket - $@"; printf "Now connected to %s:%s\n", $sock->peerhost_service; ...
This module provides a protocol-independent way to use IPv4 and IPv6 sockets. It allows new connections to be made by specifying the hostname and service name or port number. It allows for connections to be accepted by sockets listening on local ports, by service name or port number.
It uses Socket::GetAddrInfo's getaddrinfo function to convert hostname/service name pairs into sets of possible addresses to connect to. This allows it to work for IPv6 where the system supports it, while still falling back to IPv4-only on systems which don't.
getaddrinfo
It provides an API which, for most typical cases, should be a drop-in replacement for IO::Socket::INET; most constructor arguments and methods are provided in a compatible way.
Creates a new IO::Socket::IP object. If any arguments are passed it will be configured to contain a newly created socket handle, and be configured according to the argmuents. The recognised arguments are:
The socket type (e.g. SOCK_STREAM, SOCK_DGRAM). Will be inferred by getaddrinfo from the service name if not supplied.
SOCK_STREAM
SOCK_DGRAM
IP protocol for the socket connection. Will be inferred by getaddrinfo from the service name, or by the kernel from the socket type, if not supplied.
Hostname and service name for the peer to connect() to. The service name may be given as a port number, as a decimal string.
connect()
For symmetry with the accessor methods and compatibility with IO::Socket::INET, PeerAddr and PeerPort are accepted as synonyms respectively.
IO::Socket::INET
PeerAddr
PeerPort
Puts the socket into listening mode where new connections can be accepted using the accept method.
accept
Hostname and service name for the local address to bind() to.
bind()
For symmetry with the accessor methods and compatibility with IO::Socket::INET, LocalAddr and LocalPort are accepted as synonyms respectively.
LocalAddr
LocalPort
If true, set the SO_REUSEADDR sockopt
SO_REUSEADDR
If true, set the SO_REUSEPORT sockopt (not all OSes implement this sockopt)
SO_REUSEPORT
If true, set the SO_BROADCAST sockopt
SO_BROADCAST
If false, the socket will be set to nonblocking mode. If absent or true it will be in blocking mode. See NON-BLOCKING below for more detail.
NON-BLOCKING
If the constructor fails, it will set $@ to an appropriate error message; this may be from $! or it may be some other string; not every failure necessarily has an associated errno value.
$@
$!
errno
If either LocalHost or PeerHost (or their ...Addr synonyms) have any of the following special forms, they are split to imply both the hostname and service name:
LocalHost
PeerHost
...Addr
hostname.example.org:port # DNS name 10.0.0.1:port # IPv4 address [fe80::123]:port # IPv6 address
In each case, port is passed to the LocalService or PeerService argument.
port
LocalService
PeerService
Either of LocalService or PeerService (or their ...Port synonyms) can be either a service name, a decimal number, or a string containing both a service name and number, in the form
...Port
name(number)
In this case, the name will be tried first, but if the resolver does not understand it then the port number will be used instead.
As a special case, if the constructor is passed a single argument (as opposed to an even-sized list of key/value pairs), it is taken to be the value of the PeerAddr parameter. The example in the SYNOPSIS section may also therefore be written as
my $sock = IO::Socket::IP->new( "www.google.com:www" ) or die "Cannot construct socket - $@";
Return the hostname and service name for the local endpoint (that is, the socket address given by the sockname method).
sockname
If $numeric is true, these will be given in numeric form rather than being resolved into names.
$numeric
This method is used to implement the following for convenience wrappers. If both host and service names are required, this method is preferrable to the following wrappers, because it will call getnameinfo(3) only once.
getnameinfo(3)
Return the numeric form of the local address
Return the numeric form of the local port number
Return the resolved name of the local address
Return the resolved name of the local port number
Similar to the sockhost_service method, but instead returns the hostname and service name for the peer endpoint (that is, the socket address given by the peername method).
sockhost_service
peername
Return the numeric form of the peer address
Return the numeric form of the peer port number
Return the resolved name of the peer address
Return the resolved name of the peer port number
If the constructor is passed a false value for the Blocking argument, then the socket is put into nonblocking mode. When in nonblocking mode, an actual connect operation will not have been completed by the time the constructor returns, because this may block.
Blocking
connect
In order to use this mode, the caller should poll for writeability on the filehandle, each time it indicates write-readiness, the user code should call the connect method, with no arguments. Once the socket has been connected to the peer, connect will return true. If it returns false, the value of $! indicates whether it should be tried again (EINPROGRESS), or whether a permanent error has occured. This API is an extension of the IO::Socket::INET API, unique to IO::Socket::IP, because the former does not support multi-homed nonblocking connect.
EINPROGRESS
use IO::Socket::IP; use Errno qw( EINPROGRESS ); use Socket qw( SOCK_STREAM ); my $socket = IO::Socket::IP->new( PeerHost => "192.168.1.1", PeerService => "25", Type => SOCK_STREAM, Blocking => 0, ) or die "Cannot construct socket - $@"; while( !$socket->connect and $! == EINPROGRESS ) { my $wvec = ''; vec( $wvec, fileno $socket, 1 ) = 1; select( undef, $wvec, undef, undef ) or die "Cannot select - $!"; } die "Cannot connect - $!" if $!; ...
This example uses select(), but any similar mechanism should work analogously. The user code should be careful to note that the underlying descriptor may change from call to call, for example because a new socket has been constructed around it. Here using select() this is simple because $wvec is rebuilt every time, but more care would be required, for example, when using an O(1) notification mechanism such as epoll or kqueue, which takes long-lived registrations of filehandles.
select()
$wvec
epoll
kqueue
Cache the returns from sockhost_service and peerhost_service to avoid double-lookup overhead in such code as
peerhost_service
printf "Peer is %s:%d\n", $sock->peerhost, $sock->peerport;
Implement constructor args Timeout and maybe Domain. Except that Domain is harder because IO::Socket wants to dispatch to subclasses based on it. Maybe Family might be a better name?
Timeout
Domain
Family
Add new constructor args LocalAddrInfo and PeerAddrInfo to directly pass in results of getaddrinfo calls, in case user code has some way to asynchronise them to make it truely nonblocking (such as Net::LibAsyncNS.
LocalAddrInfo
PeerAddrInfo
Net::LibAsyncNS
Paul Evans <leonerd@leonerd.org.uk>
To install IO::Socket::IP, copy and paste the appropriate command in to your terminal.
cpanm
cpanm IO::Socket::IP
CPAN shell
perl -MCPAN -e shell install IO::Socket::IP
For more information on module installation, please visit the detailed CPAN module installation guide.