#!/usr/bin/perl use strict; use warnings; use IO::Socket; use threads; use Thread::Queue; use Mysql; #ignore child processes to prevent zombies $SIG{CHLD} = 'IGNORE'; #get the port to bind to or default to 8000 my $port = $ARGV[0] || 8000; ## Queue for commands input from the keyboard ## That will be sent to the currrently connected device my $qin = Thread::Queue -> new; ## Queue for the data inbound from the device my $qout = Thread::Queue -> new; my $listen_socket = IO::Socket::INET->new( LocalPort => $port, Listen => 1, Proto => 'tcp', Reuse => 1 ) or die "Cant't create a listening socket: $@"; warn "Server ready. Waiting for connections on $port ... \n"; async { ## Monitor the keyboard and forward any input ## to the currently connected client GPS device while( ) { chomp; $qin->enqueue( $_ ); } }; async{ ## Monitor the queue and do whatever with the inbound data while( my $data = $qout->dequeue ) { ## Do something with the gps data (like write it to a database?) } }; ## Spawn a new connection if the device reattaches. ## Old connections clean themselves up automatically while (my $connection = $listen_socket->accept) { threads->create ("read_data", $qin, $qout, $connection)->detach; print $connection; } sub read_data { # accept data from the socket and put it on the queue my( $qin, $qout, $socket ) = @_; while (<$socket>) { print "$_"; ## Process data from connected devices $qout -> enqueue(time." $_"); ## if there are any commands pending, send them to the GPS device while( $qin->pending ) { my $cmd = $qin->dequeue; print $socket $cmd; } } close $socket; }