Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Can someone please give me some pointers or links for writing a simple client that i want to use for testing to put a server through its paces.(on windows, which means no IO::Multiplex or IO::Event).
The easiest has been using fork under cygperl but then that rules out the use of a debugger as well as making it hard to add messages to the outgoing queue in the other process.
I tried something crude like this as well but after a couple of writes it never reaches the write sub again even with no reads coming in.
sub read_incoming { while (defined sysread $_[0],$header,9,0) # Get header for the cor +rect body length to call next; { if($header =~ m/([A-Z]{4})0+(\d{5})/) { my $messagetype = $1; sysread $_[0],$body,$2,0;#receive ng } } } sub write_outgoing { if(defined(my $line = shift(@g_queue))) { syswrite $_[0] ,$line; } } while(1) { ($r_ready, $w_ready) = IO::Select->select($read_set, $write_set, undef, $timeout); foreach my $rhandle (@$r_ready) #handle reads { read_incoming $rhandle; } foreach my $whandle(@$w_ready) #handle writes { write_outgoing $whandle; } }
I just need it to tbe async and recieve and send messages in no particular order. Thanks for any help.

Cheers

Replies are listed 'Best First'.
Re: trying to write simple sockets client on Windows
by tachyon (Chancellor) on Apr 14, 2004 at 03:29 UTC

    I presume this is the sort of thing you want (this is a server that accepts conns and listens/writes to them all asyncronously) but a client would be similar. It is not entirely clear what you actually want to do:

    use IO::Select; use IO::Socket; $lsn = new IO::Socket::INET(Listen => 1, LocalPort => 8080); $sel = new IO::Select( $lsn ); while(@ready = $sel->can_read) { foreach $fh (@ready) { if($fh == $lsn) { # Create a new socket to handle more conns $new = $lsn->accept; $sel->add($new); # register it with IO::Select } else { # Process socket my $data = <$fh>; if ( $data =~ m/exit/i ) { print $fh "Sayonara!\n"; $sel->remove($fh); $fh->close; } else { print $fh "Hello $data\n"; } } } }

    Run the server in a command window. Open any number of other command windows and telnet localhost 8080 Talk to the server and it will talk back to that telnet session until you type exit.

    cheers

    tachyon

      Thanks tachyon. All i want to do is connect to my server and send off a file of test commands one by one ,capturing the incoming replies so that they can be logged and processed and more commands added to the send queue depending on the incoming.
      I guess the closest analogy would be an IRC client where i can receive messages in reply to my client or just receive a message from another client connected to the same server.
      All the client examples i can find only deal with a very simple client thats either synchromous or only handles sends I had this before and it works great.
      die "can't fork: $!" unless defined($kidpid = fork()); if ($kidpid) { # We are the parent. Handle incoming my $header; my $body; while(1) { while (defined sysread $handle,$header,9,0) { print $header,"\n"; if($header =~ m/([A-Z]{4})(\d{5})/) { my $messagetype = $1; if($2 != 00000) { $2 =~ m/0+(\d+)/; #remove sysread $handle,$body,$1,0; #receive am +ount specified in header } check_header_type $messagetype, $body, $handle; #do t +hings with this message } } } kill("TERM" => $kidpid); # send SIGTERM to child } ############################################### # Child Process ############################################### else { # Child. handle all sends while ($line = <INPUTFILE>) { chomp $line; if(!($line =~ m/\A#/)) #check for '#' in file as comment s +ign {syswrite DEBUG, "Got Line\n"; my $bod = add_header($line); syswrite $handle, $bod; } } }
      but im stuck in cygwin, no debugging support, and passing new messages to the child process to send is starting to complicate things (from what i know)just for hacked up client.
      So really im trying to get the above working smoothly without fork.
      thanks

      Just to clarify a single important point: yes this code can handle multiple simultaneous client connections, but there is one limitation: the server can only deal with one client at any one moment in time. So if the server takes a lot of processing time to handle client input, then all other clients will have to wait in line for their turn to communicate with the server.

      This is not a big deal with most servers that communicate back and forth one a one-line-at-a-time basis, but as soon as you throw in extreme processing or any sleep()s, etc, things can back up quickly.

Re: trying to write simple sockets client on Windows
by NetWallah (Canon) on Apr 14, 2004 at 03:28 UTC
    You may want to try the new IO::All module.

    use IO::All; # A forking socket server that writes to a log my $server = io('server.com:9999'); my $socket = $server->accept('-fork'); while (my $msg = $socket->getline) { io('./mylog')->appendln(localtime() . ' - $msg'); } $socket->close;

    Offense, like beauty, is in the eye of the beholder, and a fantasy.
    By guaranteeing freedom of expression, the First Amendment also guarntees offense.