#!env perl use strict; use IO::Socket; use IO::Lambda qw(:all); use IO::Lambda::Socket qw(:all); # Returns a lambda that listens on an UDP socket, and spawns # new lambdas on every datagram. sub udp_server(&@) { my ($callback, $port) = @_; my $server = IO::Socket::INET-> new( Proto => 'udp', LocalPort => $port, Blocking => 0, ); return $! unless $server; # this lambda will be the server return lambda { # The two lines below say: on the socket $server, sleep # until the socket becomes writable, which means that we've # got a connection. On the connected socket then issue a # CORE::recv() call with max UDP packet size 64K context $server, 65536, 0; recv { # Address of the client socket, and the datagram my ( $addr, $msg) = @_; # Re-register the callback and wait again (i.e. same context $server; recv ) call again; # Instantiate a new lambda with $addr and $msg, and wait # for it to finish. It's not a blocking wait, and again() call # above makes sure that if there comes another connection meanwhile, # it will be served as well. context $callback-> (), $addr, $msg; &tail(); }} } # create a new lambda that does nothing, just a debug print sub handle_incoming_connection_udp { lambda { my ( $addr, $msg ) = @_; my ($port, $iaddr) = sockaddr_in($addr); my $host = inet_ntoa($iaddr); print "got msg '$msg' from $host:$port\n"; } } # fire up the server my $server = udp_server { handle_incoming_connection_udp } 5000; die $server unless ref $server; $server-> wait;