#! perl -slw use strict; use threads; use Thread::Queue; use IO::Socket; use IO::Select; use constant PACKETLEN => 30; my $Q = new Thread::Queue; async { my $noBlock = 1; my $lsn = IO::Socket::INET->new( Proto => 'tcp', LocalPort => 12345, Listen => SOMAXCONN, Reuse => 1, TIMEOUT => 3, ) or die "Server failed to create listener: $^E"; binmode $lsn; ioctl( $lsn, 0x8004667e, \$noBlock ); my $sel = IO::Select->new( $lsn ); my %inbufs; while( 1 ) { my @ready = $sel->can_read(1); for my $ready ( @ready ) { if( $ready == $lsn ) { my $client = $lsn->accept or next; binmode $client; ioctl( $client, 0x8004667e, \$noBlock ); $sel->add( $client ); $inbufs{ $client } = ''; } else { if( read( $ready, $inbufs{ $ready }, PACKETLEN - length( $inbufs{ $ready } ), length( $inbufs{ $ready } ) ) == 0 ) { $ready->shutdown( 2 ); $sel->remove( $ready ); $ready->close; delete $inbufs{ $ready }; next; } length( $inbufs{ $ready } ) == PACKETLEN or next; $Q->enqueue( $inbufs{ $ready } ); $inbufs{ $ready } = ''; } } } }->detach; my $c = 0; while( my $packet = $Q->dequeue ) { ## Do something with the packet printf "\r%u: $packet", ++$c; }