#!/usr/bin/perl -w # Program to connect to a server (set HOST and PORT below) # and send some commands to it randomly chosen from the # list of commands (see @COMMANDS below) with some # arguments if randomly decided. # After sending each command it displays output received # and then sleeps for some random time specified by # the command line options: commands-per-second-min and -max # When 'time-to-live' seconds have elapsed (more or less) # the client shuts down. # # Usage: client.pl TTL cps-min cps-max # TTL: will shutdown in TTL seconds more or less # cps-min, cps-max: send bettwen cps-min and cps-max # commands (request) per second to the server. # # Author: bliako # 28/09/2018 # for https://perlmonks.org/?parent=1223158;node_id=3333 # use strict; use warnings; use Net::Telnet; use Time::HiRes; my @COMMANDS = qw/PING HELLO/; my ($HOST, $PORT) = ('127.0.0.1', '1337'); if( scalar(@ARGV) != 3 ){ print STDERR "Usage : $0 time-to-live commands-per-second-min commands-per-second-max\n"; exit(1) } my ($ttl, $cps_min, $cps_max) = @ARGV; my @queue = (); my $attl = $ttl; # calculate seconds between commands (can be fractional and less than 1) # cps: commands-per-second # spc: seconds-between-commands my ($spc_min, $spc_max) = sort (1.0/$cps_min, 1.0/$cps_max); while($attl > 0 ){ # calculate sleep time before running this command my $rsbc = $spc_min + rand($spc_max-$spc_min); # get a random command my $cmd = $COMMANDS[int(rand(scalar(@COMMANDS)))]; if( rand() < 0.5 ){ # add optional args to command randomly $cmd .= " optional-argument=".int(rand(100000)); } # add command and sleep time to queue push @queue, [$cmd, $rsbc]; # reduce time-to-live $attl -= $rsbc; } # end the session push @queue, ['QUIT 123', $spc_min]; my $num_cmds = scalar(@queue); print "$0 : here is the list of comamnds and sleep times to send to server:\n"; print $_->[0].' and sleep for '.$_->[1]." s\n" for @queue; my $tel = Net::Telnet->new( Host => $HOST, Port => $PORT ) or die "telnet new failed for ${HOST}:${PORT}"; $tel->open() or die "telnet open() failed, $!"; # important to set the prompt correctly # otherwise you may get 'pattern match read eof' # see also https://www.perlmonks.org/?node_id=672565 $tel->prompt('/>/') or die "telnet prompt() failed, $!"; my $time_started = time; print "$0 : starting...\n"; foreach (@queue){ my ($cmd, $rsbc) = @$_; print "$0 : sending command '$cmd' ... \n"; my @lines = $tel->cmd($cmd); print "$0 : data received:\n".join("\n", @lines)."\n--- end data received.\n"; print "$0 : sleeping for $rsbc s ...\n"; Time::HiRes::sleep($rsbc); } print "$0 : shutting down ...\n"; $tel->close() or die "close(), $!"; print "$0 : done send $num_cmds commands in ".(time-$time_started)." s.\n"; exit(0);