Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

UDP Listener / Server

by webfreakin (Initiate)
on Dec 30, 2007 at 09:34 UTC ( [id://659588]=perlquestion: print w/replies, xml ) Need Help??

webfreakin has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I need to write a heavy duty UDP listener / server that is capable of listening to 1000's of UDP clients. Each client will send a 128 bytes data packets every few seconds and all of these need to be received on the UDP listener / server. I would like to what is my best approach? What modules from CPAN to use? Any help would be appreciated. Thanks, Ragger

Replies are listed 'Best First'.
Re: UDP Listener / Server
by ikegami (Patriarch) on Dec 30, 2007 at 10:15 UTC

    IO::Socket::INET is a handy interface to create the socket.

    If you have multiple server sockets, IO::Select will allow you to wait them.

    recv will allow you to receive from the socket.

    You might need unpack to extract the data from the packet.

    Encode's decode will translate strings of bytes into strings of characters.

Re: UDP Listener / Server
by valdez (Monsignor) on Dec 30, 2007 at 10:42 UTC

    After reading what ikegami suggested, take a look also at perlipc man page; if you think this is too complicate, try with Net::Server, which will help you doing what was described in our comments.

    Ciao, Valerio

Re: UDP Listener / Server
by zentara (Archbishop) on Dec 30, 2007 at 16:36 UTC
    From my understanding, UDP is for simple messaging and they are not gauranteed to make it thru, like TCP is. So if your UDP server is hit with 1000's of messages at the same time, you might want to switch to TCP(with IO::Select) OR have multiple servers listening to lighten the possible simultaneous load.

    Anyways, this is from the Cookbook Chapter 17

    #server #!/usr/bin/perl -w # udpqotd - UDP message server use strict; use IO::Socket; my($sock, $newmsg, $hishost, $MAXLEN, $PORTNO); $MAXLEN = 1024; $PORTNO = 5151; $sock = IO::Socket::INET->new( LocalPort => $PORTNO, Proto => 'udp') or die "socket: $@"; print "Awaiting UDP messages on port $PORTNO\n"; while ($sock->recv($newmsg, $MAXLEN)) { my($port, $ipaddr) = sockaddr_in($sock->peername); $hishost = gethostbyaddr($ipaddr, AF_INET); print "Client $hishost said $newmsg\n"; $sock->send("CONFIRMED: $newmsg "); } die "recv: $!"; # You can't use the telnet program to talk to this server. You # have to use a dedicated client.
    #client #!/usr/bin/perl -w # udpmsg - send a message to the udpquotd server use IO::Socket; use strict; my($sock, $msg, $port, $ipaddr, $hishost, $MAXLEN, $PORTNO, $TIMEOUT); $MAXLEN = 1024; $PORTNO = 5151; $TIMEOUT = 5; $sock = IO::Socket::INET->new(Proto => 'udp', PeerPort => $PORTNO, PeerAddr => 'localhost') or die "Creating socket: $!\n"; $msg = 'testmessage'.time; $sock->send($msg) or die "send: $!"; eval { local $SIG{ALRM} = sub { die "alarm time out" }; alarm $TIMEOUT; $sock->recv($msg, $MAXLEN) or die "recv: $!"; alarm 0; 1; # return value from eval on normalcy } or die "recv from localhost timed out after $TIMEOUT seconds.\n"; print "Server $hishost responded $msg\n"; # This time when we create the socket, we supply a peer host and # port at the start, allowing us to omit that information in the send. # We've added an alarm timeout in case the server isn't responsive, # or maybe not even alive. Because recv is a blocking system call that + # may not return, we wrap it in the standard eval block construct # for timing out a blocking operation.

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Multi-threaded UDP Listener / Server
by Anonymous Monk on Dec 31, 2007 at 05:52 UTC
    Thanks for those suggestions! I have been thinking and my requirement could be better titled as - "Multi-threaded UDP Listener / Server" I have been thinking of using POE and/or forking but am not sure what might be a better approach. I will always have data being received on the port. This could be one packet, 10's or 100's or 1000's. I assume I cannot use TCP because of the fact the TCP will send out an acknowledge, it might take more time than UDP and will also use server resources. I might be wrong, so please correct me. Further, my UDP clients have nothing built in to acknowledge the server. I was looking at the pre-forking server script in the Perl cookbook and was wondering if that is the right approach? Thanks for the help. Ragger

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://659588]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-19 20:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found