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

my client-script:
use strict; use IO::Socket; my ($host,$port) = ("localhost","9000"); my $remote = IO::Socket::INET->new( Proto => "udp", PeerAddr => $host, PeerPort => $port ) or log_die "cannot connect to $host - $port\n"; die("[Connected to $host:$port]\n"); syswrite($remote, "Yooo\n")
Server-script:
use strict; use IO::Socket; my $socket=IO::Socket::INET->new(LocalAddr => 'localhost', LocalPort => 9000, Proto => 'udp') or die "socket: $!"; my $length; while (defined($length=sysread($socket, my $buffer, 65536)) && $length + != 0) { die "sysread: $!" if (!defined($length)); # When I have a connect from a client start another very big script +:) system('./sleep.pl'); exit; }
So as you see when there's a connect from a client, I need to start another proces.

1) client -> server -> start ./sleep

2) client -> server -> ./sleep still running -> don't wait

3) client -> server -> ./sleep still running -> don't wait

4) client -> server -> sleep not running? start ./sleep

=> for these 4 cases the server will start sleep 4 times in a row . This I don't want, I want ./sleep only to start when client connects and there is no other sleep running.

For the moment my existing codes makes sure only one ./sleep process is running at a time(thanks to spawning a child and a wait() in the parent). In case 2 and 3 there should never run a ./sleep. only when there is a new connect when there is no ./sleep running.

--
My opinions may have changed,
but not the fact that I am right

Replies are listed 'Best First'.
Re: UDP and IO::Socket
by agoth (Chaplain) on Jan 15, 2002 at 19:29 UTC
    Well, you could have your server write a sleep.pid file when it gets a request in.
    If the next request gets a response from calling kill 0, server.pid; then it doesn't start another instance. Thats what I do to stop initiating multiple instances of remote servers.
      It's not it doesn't start multiple instances when it's running. That I have solved. But when the client connects ten times, the 10 connects keep on waiting in the queue and my sleep will be run 10 times consecutive.

      --
      My opinions may have changed,
      but not the fact that I am right

        Then you need to provide a slightly more complex server instance, that is a multiplexed reader. This will not wait for individual actions to complete and will allow you to close incoming reads if the sleep script is currently running yet respond to any read if sleep has finished?
        while (1) { ($read, $write, $err) = IO::Select->select($sockin, $sockout, $sock +err, 1); for $sock (@$read) { $sock->recv($data, 1024 * 64, 0); next if $! == EAGAIN() || $! == EWOULDBLOCK(); next if (-e 'server.pid'); system ('./sleep.pl'); } }