http://www.perlmonks.org?node_id=826330

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

OK, i'm not going to bother posting what i've tried so far, since i've tried pretty much everything i could find (except for what would work for me). Basicly, it's a client/server thing. The concept should be fairly simple. (pseudo)Code snippets of what i'm doing as follows:
use warnings; # Handy use strict; # Even more handy use IO::Socket::INET; my $socket = IO::Socket::INET->new ( LocalPort => $config{'listenport'}, Proto => 'udp', Reuse => 1, ) or die "Can't create listening socket: $@\n"; while (1) { my $indata; # Read some data from the serial port # Read some data from a few files # ~300 lines of calculations go here, putting it all into $out +data when done shipout($outdata); # flush buffers, and other stuff } sub shipout { my $datatoship = shift; # these lines should be replaced by something that # that sends the contents of $datatoship to # everyone (or anyone) that is connected to $socket # if none is connected, just move on. } __END__
So, yeah.. basicly, I need to send the result of the calculations done in the mainloop to anyone that might be connected to the socket. The communications are one-way, as in no clients ever sending anything to the server, as they just connect to read a stream of data calculated by the server. I have looked at many examples, but i have still not found one that deals with one-way comms, except from client->server, and i need it the other way around. I thought this should be fairly straightforward, and i still do, i'm just sure that i'm missing something very vital.

Replies are listed 'Best First'.
Re: UDP server with IO::Socket::INET
by ikegami (Patriarch) on Mar 03, 2010 at 04:32 UTC

    something that sends the contents of $datatoship to everyone (or anyone) that is connected to $socket

    UDP is connectionless. Depending on how you look at it, you're never connected with anyone, or you're always connected with every IP address.

    Perhaps you mean "everyone that has previously sent some connect request", in which case you need to keep track of everyone that sent you a connect request (and didn't send you a disconnect request), and send the message to each of those individually. What a connect request might resemble is up to you. It could be as simple as sending a message with the string "connect".

    Not relevant to your current dilemma, but you talked of a UDP stream. However, UDP is not a streaming protocol. Each Datagram is independent. They are not necessarily received in the same order as they are sent (unlike streaming protocols like TCP).

    Finally, you might need to know that UDP is an unreliable protocol. That means you aren't notified if the delivery of the packet was successful. (Conversely, TCP is a reliable protocol. Communication might not be successful, but you'll know if it wasn't.)

      Well, i guess i could have every client that "connects" send a "yup, i'm here"-packet. However, would this mean that every client would have to send something to the server every time they want to receive something? Also, yes. My choice of words was inapropriate, since the data isn't really a stream. It's just so many small packets that it makes more sense to me to look at it as a stream, rather than packets, hehe. And as for reliability, it's not really important. The data to be sent is calculated very often, due to changes, so reception of all of them is far from critical, as long as a majority of them is received. Also, the data will only be sent over a LAN anyway.

        I don't see any (easy) way to get around having to have your clients let the server know they want to receive data. I suppose you can have the clients just close the socket when they're tired of listening and the server could remove them when the send fails but you still need some way to know which clients to send to.

        Since you're on a LAN, I suppose you could send to the broadcast address and let the clients listen when they want to. If you are dealing with a sane OS you might want to check out IO::Socket::Multicast.

        However, would this mean that every client would have to send something to the server every time they want to receive something?

        No, just once. Well, maybe once in a while. The server should forget connects that it has received a long time ago to avoid sending to a machine that didn't properly disconnect, but that's no longer interested.

Re: UDP server with IO::Socket::INET
by bot403 (Beadle) on Mar 03, 2010 at 17:33 UTC

    This looks like it would benefit from The Spread Toolkit and its associated perl bindings rather than rolling your own solution. Its very lightweight and pretty easy to setup and use. Basically you can set up a message group that the server and clients join. The clients would just listen for messages they are interested in and the server can broadcast as many messages as it wants wether there are listeners or not. The spread deamon will take care of all the hard work for you.

Re: UDP server with IO::Socket::INET
by eric256 (Parson) on Mar 19, 2010 at 19:32 UTC

    I do something similar, i have a server that needs to send info out to clients on a regular basis but i didn't want to worry about maintaining client lists and connections. I just used a UDP broadcast in my case, but a multicast would work just as well.


    ___________
    Eric Hodges