#!/usr/bin/perl -w use strict; use IO::Select; use IO::Socket; my $port = 8080; my $lsn = new IO::Socket::INET(Listen => 5, LocalPort => $port, Proto => 'tcp', ReuseAddr => 1); my $sel = new IO::Select( $lsn ); my $id = 1; print "Listening on socket $port\n"; my $error = 0; while(!$error) { my @ready = $sel->can_read(1.0); if (scalar @ready) { for my $fh (@ready) { if($fh == $lsn) { my $client = $lsn->accept; ConnHandler->new($sel, $client, $id++); } elsif(my $hdlr_ref = ConnHandler::GetHandler{"$fh"}) { print "Found handler\n"; $$hdlr_ref->ReadData(); } else { print "ERROR: failed to look up $fh in {" . join(',', ConnHandler::GetKeys()) . "}, of size " . scalar ConnHandler::GetKeys() . "\n"; $error = 1; } } } else { # Timeout for my $handler (ConnHandler::GetHandlers()) { if ($handler->WaitExpired()) { $handler->SendMsg("This is only a test"); $handler->Close(); my $fh = $handler->{fh}; ConnHandler::DeleteHandlerByKey("$fh"); } } } } exit 0; ################ package ConnHandler; my %Handlers = (); my $resp_delay = 5; my $debug = 1; sub GetHandler($) { my $key = shift; return \$Handlers{$key}; } sub DeleteHandlerByKey($) { my $key = shift; delete $Handlers{$key}; } sub GetHandlers() { return values %Handlers; } sub GetKeys() { return keys %Handlers; } sub new($$$$) { my $pkg = shift; my $self = bless { sel => shift, fh => shift, id => shift, ts => time } => $pkg; my $fh = $self->{fh}; $self->{sel}->add($fh); $Handlers{"$fh"} = $self; print "ConnHandler::new() [id:" . $self->{id} . "]\n"; } sub ReadData($) { my $self = shift; my $msg; sysread($self->{fh}, $msg, 512); my $ts = localtime; print "[$ts, id=" . $self->{id}. "] RECV $msg\n"; } sub WaitExpired($) { my $self = shift; my $dif = time - $self->{ts}; my $flag = $dif >= 5; my $ts = localtime; if ($flag) { print "[$ts, id=$self->{id}] EXP: $dif\n"; } else { print "[$ts, id=$self->{id}] NOT EXP: $dif\n"; } return $flag; } sub SendMsg($$) { my $self = shift; my $msg = shift; syswrite($self->{fh}, $msg); my $ts = localtime; print "[$ts, id=$self->{id}] SENT $msg\n"; } sub Close($) { my $self = shift; $self->{sel}->remove($self->{fh}); $self->{fh}->close; my $ts = localtime; print "[$ts, id=$self->{id}] CLOSED\n"; }