#!/usr/bin/perl use strict; use warnings; use IO::Socket::INET qw( ); use IO::Select qw( ); sub process_msg { my ($client, $msg) = @_; chomp $msg; my $host = $client->peerhost; print "$host said '$msg'\n"; return lc($msg) eq 'quit; } my $server = IO::Socket::INET->new( ... ) or die("Couldn't create server socket: $!\n"); my $select = IO::Select->new($server); my %bufs; while (my @ready = $select->can_read) { for my $fh (@ready) { if ($fh == $server) { my $client = $server->accept; $select->add($client); $bufs{fileno($client)} = ''; my $host = $client->peerhost; print "[Accepted connection from $host]\n"; } else { our $buf; local *buf = \$bufs{fileno($fh)}; my $rv = sysread($fh, $buf, 64*1024, length($buf)); if (!$rv) { my $host = $fh->peerhost; if (defined($rv)) { print "[Connection from $host terminated]\n"; } else { print "[Error reading from host $host: $!]\n"; } process_msg($fh, $buf) if length($buf); delete $bufs{fileno($fh)}; $sel->remove($fh); next; } while ($buf =~ s/\G(.*\n)//g) { if (!process_msg($fh, "$1")) { my $host = $fh->peerhost; print "[Connection from $host terminated]\n"; delete $bufs{fileno($fh)}; $sel->remove($fh); last; } } } } }