#! /usr/bin/perl use strict; use warnings; use IO::Socket::INET6; use Time::HiRes qw(sleep); use POSIX; @ARGV==5 or die "$0 "; my($hostname,$port,$string,$timeout,$tries)=@ARGV; our $try; sub ts() { return localtime()." PID=$$ #$try: "; } for $try (1..$tries) { warn ts()."connect($hostname,$port)...\n"; my $sock=IO::Socket::INET6->new( "Proto" =>"tcp", "PeerAddr"=>$hostname, "PeerPort"=>$port, "Timeout"=>$timeout, ); if (!$sock) { my $e=$!+0; warn ts()."connect($hostname,$port)=$e=$!"; sleep $timeout if $e!=ETIMEDOUT; next; } warn ts()."connect($hostname,$port): done.\n"; my $buf=""; my $remains=$timeout; while ($remains>0) { my $rin=""; vec($rin,fileno($sock),1)=1; my($nfound,$timeleft)=select($rin,"",$rin,$remains); die "select nfound=$nfound: $!" if $nfound<0; die "select timeleft=$timeleft" if $timeleft<0; $remains=$timeleft; if (!$nfound) { $remains==0 or die "remains=$remains"; last; } my $c; my $got=sysread $sock,$c,1; my $fail; if (!defined $got) { warn ts()."sysread: $!"; $fail=1; } if ($got==0) { warn ts()."sysread: EOF"; $fail=1; } if (!$fail) { $got==1 or die "sysread=$got!=1"; length($c)==1 or die "sysread->c=".length($c)."!=1"; $buf.=$c; } last if length($buf)>=length($string); # warn ts()."remains=<$remains> buf=<$buf>\n"; last if $fail; } close $sock or warn ts()."close: $!"; if ($buf eq $string) { warn ts()."PASS\n"; print "PASS\n"; exit 0; } warn ts()."buf=<$buf>, sleep $remains"; sleep $remains or warn ts()."sleep=$!"; } $try=$tries; warn ts()."FAIL\n"; print "FAIL\n";