The usual answer for this is to use select(), probably via IO::Select (since it's easier and OO). select() will let you wait until something of interest happens on zero or more file handles (including sockets and regular files), or until a timeout. The "something of interest" includes a handle being able to read, write, or having an exceptional condition.
If you want to see an entire framework built around select (more or less), look at POE. | [reply] |
Here is a typical generic wait for something or timout piece of code. In this case we wait for an exclusive file lock
my $timeout = 15; # timeout in seconds
my $delay = 1; # number of seconds between re-tries
open (FILE, ">$file") or die "Unable to create file '$file': $!\n";
my $count = 0;
until (flock FILE, LOCK_EX) {
sleep $delay;
$count += $delay;
die "Can't lock file '$file': $!\n" if $count >= $timeout;
}
cheers
tachyon | [reply] [d/l] |
Yes, as bikeNomad suggested, you can use the four-argument select() or IO::Select.
This way avoids the so-called busy-waiting by letting the kernel does the scanning of array of file descriptors of interest.
Once your socket is ready to read or write, the kernel wakes up your program, which then handles it.
Here's a simple client to send HEAD to a httpd:
#!/usr/bin/perl -w
use IO::Socket;
$|++;
my $client = IO::Socket::INET->new(
PeerAddr => 'www.satunet.com',
PeerPort => 80,
Proto => 'tcp',)
or die "Can't connect: $!";
$rin = $rout = $win = $wout = '';
vec($rin, $client->fileno, 1) = 1;
vec($win, $client->fileno, 1) = 1;
while (1) {
if (select($rout = $rin, $wout = $win, undef, 5) > 0) {
if (vec($rout, $client->fileno, 1)) {
while (<$client>) { print "Client read: $_" }
$client->close;
} elsif (vec($wout, $client->fileno, 1)) {
print $client "HEAD / HTTP/1.0\r\n\r\n";
}
} else { exit }
}
Using IO::Select is much more convenient since it does the bit-vector works behind the curtain,
as well as its nice OO interface.
POE is also good, but it requires you to have some basic knowledge about state machine, otherwise its
programming style may be confusing. I'd recommend using JPRIT's Event module
if you want to explore the full power of event-driven programming.
| [reply] [d/l] |
or you can do $var=<$socket> That waits until the
Socket is ready.(PM's: See this**Warning: Incredibly newbie-ish question**
That means he doesn't know that a Socket is like a File) | [reply] [d/l] |
$var = <$socket>;
only works if the data coming into the socket happens to be delimited by newlines. Not all network protocols are newline-delimited. | [reply] [d/l] |