1#!/usr/bin/perl -w 2 3use blib; 4use IO::KQueue; 5use IO::Socket; 6 7my $server = IO::Socket::INET->new( 8 LocalAddr => "127.0.0.1:3069", 9 Listen => 10, 10 Blocking => 0, 11 Reuse => 1, 12 ); 13 14IO::Handle::blocking($server, 0); 15 16my $kq = IO::KQueue->new(); 17 18$kq->EV_SET(fileno($server), EVFILT_READ, EV_ADD, 0, 5); 19 20my %users; 21while (1) { 22 my @ret = $kq->kevent(); 23 if (!@ret) { 24 die "No kevents: $!"; 25 } 26 27 foreach my $kevent (@ret) { 28 my $fd = $kevent->[KQ_IDENT]; 29 30 if ($fd == fileno($server)) { 31 my $client = $server->accept(); 32 IO::Handle::blocking($client, 0); 33 if (!$client) { 34 warn("accept() failed: $!"); 35 next; 36 } 37 38 $kq->EV_SET(fileno($client), EVFILT_READ, EV_ADD); 39 40 $users{fileno($client)} = $client; 41 } 42 else { 43 my $client = $users{$fd} || die "Unknown fd: $fd"; 44 my $buf; 45 my $blen = $client->read($buf, 8096); 46 47 if (!$blen) { 48 # eof 49 delete $users{$fd}; 50 $client->close; 51 } 52 elsif ($blen == -1) { 53 # error 54 die "read error on $fd: $!"; 55 } 56 else { 57 foreach my $f (keys %users) { 58 next if $f == $fd; 59 $users{$f}->print($buf); 60 } 61 } 62 } 63 } 64}