#! perl -slw
use strict;
use threads;
use threads::shared;
use IO::Socket::INET;
use Term::ReadKey;
$| = 1;
our $BASE ||= 2000; ## base port
our $PORTS ||= 5; ## Number of consecutive ports to open
our $STATUS ||= 1; ## decimal seconds between status updates
my $running : shared = 0;
my $stop : shared = 0;
my %status : shared;
sub listener {
$running++;
my( $port ) = @_;
$status{ $port } = 'started';
my $socket = IO::Socket::INET->new(
LocalPort => $port,
Type => SOCK_STREAM,
Listen => 1,
Reuse => 1,
Timeout => 10,
) or die "Error: $!\n";
until( $stop ) {
while( my $client = $socket->accept ) {
$status{ $port } = 'opened';
while( <$client> ) {
chomp;
$status{ $port } = 'Receiving';
print $client "$port: $_";
$status{ $port } = 'Replying';
}
close $client;
$status{ $port } = 'Closed';
}
}
$status{ $port } = 'Stopping';
$running--;
}
warn "Starting listeners\n";
my @listeners = map{
threads->new( \&listener, $_ )->detach
} $BASE .. $BASE + $PORTS;
sleep 1 while $running < @listeners; ## Giv'em a timeslice
printf( "\r%s\t", join "\t",
map{ "$_:$status{ $_ }" } sort keys %status
) and Win32::Sleep( $STATUS )
while $running
and not defined( ReadKey( -1 ) );
$stop = 1;
printf( "\r%s\tWaiting for:$running", join "\t",
map{ "$_:$status{ $_ }" } sort keys %status )
and Win32::Sleep( $STATUS )
while $running;
warn "\nAll done\n";
####
#! perl -slw
use strict;
use IO::Socket::INET;
$| = 1;
my $port = $ARGV[ 0 ] || die "No port number";
my $socket = IO::Socket::INET->new(
PeerAddr => 'localhost',
PeerPort => $port,
Proto => "tcp",
Type => SOCK_STREAM
) or die "Couldn't connect to localhost:$port : $!\n";
$socket->autoflush;
for ( 1 .. rand 1000 ) {
warn "Sending '$_'\n";
print $socket "$port: $_";
my $read = <$socket>;
warn "Got '$read'\n";
Win32::Sleep rand 10;
}
close $socket;
####
for /l %i in (2000,1,2100) do @start /b perl 416434-c.pl %i