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

I sincerely hope I did not miss the answer to my question in another thread.

I am working on a UDP service to interact with some SIP phones and I am very new to socket programming, and new to Perl.

I have been using IO::Socket::INET to create a socket and respond to incoming messages. I want to ultimately create a forking (or threading, or coroutine-ing) service which immediately spawns on receipt of a request for obvious reasons involving concurrency.

If I pass my socket handle (created by IO::Socket::INET->new()) to the new process/thread/coroutine, will I be able to continue a conversation in the child line of execution whilst receiving new messages in the parent line of execution, or must I build my own system of channels to route messages from the same origin to the correct child line of execution?

Please help me remove my head from where the sun doesn't shine.

Replies are listed 'Best First'.
Re: Socket programming
by zwon (Abbot) on Aug 08, 2011 at 00:55 UTC

    Forking or starting a new thread on every new UDP packet doesn't sound like a good idea to me, you will more probably lose performance rather than gain.

Re: Socket programming
by thenaz (Beadle) on Aug 08, 2011 at 03:01 UTC

    I agree with zwon that forking or spawning a thread each time a UDP datagram shows up is probably not the way to go (especially since Perl ithreads are somewhat resource intensive).

    You may choose to use an event loop, which is much lighter-weight, and offers the ability to process things asynchronously. Check out IO::Poll. But reading your last paragraph/question, I'm not sure that's really what you want.

    In UDP, every packet is independent (i.e. UDP is connectionless), so you don't end up with a client socket object that you can dispatch to a thread (like you would in TCP). What you might want to do, is to pre-fork, or pre-spawn some threads, and then as you read packets off the socket in the main thread, examine them as needed and route to the appropriate child thread/process.

    Of course, depending on what you are doing, I can't shake the feeling that you may not actually need threads at all. Why can't you just receive a packet, process it, then receive another, etc--all on the same thread?

      I think you're correct. I can handle the incoming packets on the same thread. This was actually very helpful because I forget that UDP is stateless - hopefully my bone-headed question helps someone out in the future.

      My goal is to create a simple SIP proxy in our very non-standard environment. So, what I should do is create a fork (or what-have-you) for each new unique conversation identifier (as required in SIP) and do exactly what you said in your third paragraph.

        Also see Net::SIP, which should have large parts of a SIP client and server.

Re: Socket programming
by chubako (Acolyte) on Aug 08, 2011 at 05:10 UTC
    Not sure that it works right, but it works. :)
    use strict; use warnings; use Socket; use AnyEvent; my $udp_server my $udp_socket; sub start_udp_server { my $port = shift || 9000; my $proto = getprotobyname('udp'); my $paddr = Socket::sockaddr_in($port, Socket::INADDR_ANY); socket($udp_socket, Socket::PF_INET, Socket::SOCK_DGRAM, $proto); bind($udp_socket, $paddr); $udp_server = AE::io $udp_socket, 0, sub { my $buff; my $addr = recv($udp_socket, $buff, 256, 0); print $buff; } } start_udp_server(); my $ae_timer = AE::timer 10, 10, sub { print "timer tick\n"; } AE::cv->recv;
    You can check it with nc/netcat/ncat:
    ncat -u localhost 9000