IO::Socket::Timeout - IO::Socket with read/write timeout
version 0.20
use IO::Socket::With::Timeout; # creates a IO::Socket::INET::With::Timeout object my $socket = IO::Socket::INET->new::with::timeout( Timeout => 2, ReadTimeout => 0.5, # other standard arguments ); my $socket = IO::Socket::UNIX->new::with::timeout( Timeout => 2, ReadTimeout => 0.5, WriteTimeout => 0.5, # other standard arguments ); my $socket = IO::Socket::INET->new::with::timeout( Timeout => 2, ReadWriteTimeout => 0.5, # other standard arguments ); # When using the socket: use Errno qw(ETIMEDOUT EWOULDBLOCK); print $socket $request; my $response = <$socket>; if (! $response && ( 0+$! == ETIMEDOUT || 0+$! == EWOULDBLOCK )) { die "timeout reading on the socket"; }
IO::Socket provides a way to set a timeout on the socket, but the timeout will be used only for connection, not for reading / writing operations.
IO::Socket
This module provides a way to set a timeout on read / write operations on an IO::Socket instance, or any IO::Socket::* modules, like IO::Socket::INET.
IO::Socket::*
IO::Socket::INET
To be able to work with any class that is or inherits from IO::Socket, the interface of this module is a bit unusual.
IO::Socket::INET-new::with::timeout(...)> will return an instance of IO::Socket::INET, as if it had been called with IO::Socket::INET-new(...)>. However, it'll apply some mechanism on the resulting socket object so that it times out on read, write, or both.
IO::Socket::INET-
The way the socket will timeout ( on connection, read, write, how long), can be specified with these parameters:
This is the default parameter that already exists in IO::Socket. If set to a value, the socket will timeout at connection time.
If set to a value, the socket will timeout on reads. Value is in seconds, floats accepted.
If set to a value, the socket will timeout on writes. Value is in seconds, floats accepted.
If set to a value, the socket will timeout on reads and writes. Value is in seconds, floats accepted. If set, this option superseeds ReadTimeout and WriteTimeout.
There is an other way to create sockets from scratch, via socketpair. As for the new constructor, this module provides its counterpart with timeout feature.
socketpair
new
IO::Socket::INET-socketpair::with::timeout(...)> will return two instances of IO::Socket::INET, as if it had been called with IO::Socket::INET-socketpair(...)>. However, it'll apply some mechanism on the resulting socket object so that it times out on read, write, or both.
my $current_timeout = $socket->read_timeout(); $socket->read_timeout($new_timeout);
Get or set the read timeout value for a socket created with this module.
my $current_timeout = $socket->write_timeout(); $socket->write_timeout($new_timeout);
Get or set the write timeout value for a socket created with this module.
$socket->disable_timeout;
Disable the read and write timeouts for a socket created with this module.
$socket->enable_timeout;
Re-enable the read and write timeouts for a socket created with this module.
my $is_timeout_enabled = $socket->timeout_enabled(); $socket->timeout_enabled(0);
Get or Set the fact that a socket has timeouts enabled.
You can change the timeout settings of a socket after it has been instanciated.
use IO::Socket::With::Timeout; # create a socket with read timeout my $socket = IO::Socket::INET->new::with::timeout( Timeout => 2, ReadTimeout => 0.5, # other standard arguments ); # change read_timeout to 5 and write timeout to 1.5 sec $socket->read_timeout(5) $socket->write_timeout(1.5) # actually disable the timeout for now $socket->disable_timeout() # when re-enabling it, timeouts value are restored $socket->enable_timeout()
When a timeout (read, write) is hit on the socket, the function trying to be performed will return undef or empty string, and $! will be set to ETIMEOUT or EWOULDBLOCK. You should test for both.
undef
$!
ETIMEOUT
EWOULDBLOCK
You can import ETIMEOUT and EWOULDBLOCK by using POSIX:
POSIX
use Errno qw(ETIMEDOUT EWOULDBLOCK);
If you want to implement a try / wait / retry mechanism, I recommend using a third-party module, like Action::Retry. Something like this:
Action::Retry
my $socket; my $answer; my $action = Action::Retry->new( attempt_code => sub { # (re-)create the socket if needed $socket && ! $socket->error or $socket = IO::Socket->new::with::timeout(ReadTimeout => 0.5); # send the request, read the answer $socket->print($_[0]); defined($answer = $socket->getline) or die $!; $answer; }, on_failure_code => sub { die 'aborting, to many retries' }, ); my $reply = $action->run('GET mykey');
Action::Retry, IO::Select, PerlIO::via::Timeout, Time::Out
Thanks to Vincent Pitt, Christian Hansen and Toby Inkster for various help and useful remarks.
Damien "dams" Krotkine
This software is copyright (c) 2013 by Damien "dams" Krotkine.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install IO::Socket::Timeout, copy and paste the appropriate command in to your terminal.
cpanm
cpanm IO::Socket::Timeout
CPAN shell
perl -MCPAN -e shell install IO::Socket::Timeout
For more information on module installation, please visit the detailed CPAN module installation guide.