use IO::Socket::INET; use IO::Select; use Errno qw(EAGAIN); my $timeout = 60; my $socket = IO::Socket::INET->new( PeerAddr => "...", PeerPort => "1234", Proto => 'tcp', ) or die "Cannot create new socket: $!";; my $request = "..."; unless ( sock_write($socket, \$request, length($request)) ) { die "sock_write: socket write error ($!)"; } print "wrote $request to the socket\n"; my $len = ...; my $response = ""; unless ( sock_read($socket, \$response, $len) ) { die "sock_read: socket read error ($!)"; } print "read $response from the socket\n"; exit; # sock_read( # $socket - IO::Socket::INET socket to read from # \$msg - Reference to hold the read data # $len - number of bytes to read from the socket #) # returns: original reference to the data, or undef sub sock_read { my $socket = shift; my $buf = shift; my $len = shift; my $offset = 0; my $n = 0; my $sel = IO::Select->new($socket); while ( $offset < $len ) { unless ( $socket ) { warn "Socket became undef during read!"; return undef; } unless ($sel->can_read($timeout)) { warn "Socket read timed out"; return undef; } $n = $socket->sysread($$buf, $len-$offset, $offset); # Check for "Resource temporarily unavailable" error, and clear it. # This just means that we can't write to the socket "just now" since it's # buffer is full. if ($!{EAGAIN}) { warn "Socket would read block!"; $! = 0; # Clear the error $n = 0; # "Define" $n } unless ( defined($n) ) { return undef; } if ((not $!{EAGAIN}) && ($n == 0)) { warn "Socket read returned no data: unknown comms error!"; return undef; } $offset += $n; } return $buf; } # sock_write( # $socket - IO::Socket::INET socket to write to # \$msg - Reference to hold the data to write # $len - number of bytes to write to the socket #) # returns: original reference to the data, or undef sub sock_write { my $socket = shift; my $buf = shift; my $len = shift; my $offset = 0; my $n = 0; my $sel = IO::Select->new($socket); while ( $offset < $len ) { unless ( $socket ) { warn "Socket became undef during write!"; return undef; } unless ($sel->can_write($timeout)) { warn "Socket write timed out"; return undef; } $n = $socket->syswrite($$buf, $len-$offset, $offset); # Check for "Resource temporarily unavailable" error, and clear it. # This just means that we can't write to the socket "just now" since it's # buffer is full. if ($!{EAGAIN}) { warn "Socket write would block!"; $! = 0; # Clear the error $n = 0; # "Define" $n } unless ( defined($n) ) { return undef; } if ((not $!{EAGAIN}) && ($n == 0)) { warn "socket failed to write any data!"; return undef; } $offset += $n; } return $buf; }