in reply to Re: Using IO::Socket
in thread Using IO::Socket

Pretty good in fact, but it has a few flaws:

Here is a (only sligtly tested) version of how I would do it when using IO::Socket::INET and IO::Select (in reality I would use POE). Like you I will assume the protocol does pipelining, otherwise you should immediately start checking for readability to drain pending output that can block the server. I'm also assuming that the server finishes with EOF, otherwise you might already want to start checking for your target string inside the read loop.

#! /usr/bin/perl -w use strict; use IO::Socket::INET; use IO::Select; use POSIX qw(EWOULDBLOCK EINTR); my $timeout = 180; my ($host, $port, $string) = @ARGV; my $too_late = time()+$timeout; my $socket = IO::Socket::INET->new(PeerAddr => "$host:$port", Blocking => 0) || die "Could not connect to $host:$port: $!\n"; # Write (also handles connect, since being connected is a writability +event) $SIG{PIPE} = "IGNORE"; my $command = "EDMSFT|$string|\@\n"; my $select = IO::Select->new($socket); while ($command ne "") { my $left = $too_late - time(); if ($left <= 0) { print "TIMEDOUT\n"; exit; } next unless $select->can_write($left); if (defined(my $rc = syswrite($socket, $command))) { substr($command, 0, $rc, ""); } else { next if $! == EWOULDBLOCK || $! == EINTR; die "Error writing to $host:$port: $!\n"; } } # Read my $text = ""; while (1) { my $left = $too_late - time(); if ($left <= 0) { print "TIMEDOUT\n"; exit; } next unless $select->can_read($left); my $rc = sysread($socket, $text, 4096, length $text); if (!$rc) { last if defined $rc; # EOF next if $! == EWOULDBLOCK || $! == EINTR; die "Error reading from $host:$port: $!\n"; } } $text =~ /\Q$string\E/ || die "Unexpected answer from $host:$port: $text"; print "GOOD\n";

Replies are listed 'Best First'.
Re^3: Using IO::Socket
by Earindil (Beadle) on Oct 12, 2004 at 17:09 UTC
    Thanks much. I'll implement what I can use and see how it goes. Really appreciate the input. The server should never send an EOF. It's a continuous stream of data. The query string was added because when the app is broken, it either outputs nothing or outputs one short heartbeat every 30 secs or so (that doesn't contain the query string).