A snippet would have been nice, but I think the answer is relatively simple - avoid the problem altogether by setting the socket to operate in non-blocking mode with fcntl. Once you've done this, when you call accept on that socket and there is no connection actually waiting there, then it should return undef and set $! to EWOULDBLOCK.
use Fcntl qw/F_GETFL, F_SETFL, O_NONBLOCK/;
$flags = fcntl(SOCK_HANDLE, F_GETFL, 0)
or die "Can't get flags for socket: $!";
$flags = fcntl(SOCK_HANDLE, F_SETFL, $flags | O_NONBLOCK)
or die "Can't set flags for socket: $!";
source: Programming Perl 3 | [reply] [d/l] |
Many thanks to you, Monks!
After much fiddling with the ideas here, I decided on another way of doing it. Here's what I decided:
I'm using IO::Socket::INET, so my ports are defaulted to non-blocking. Sadly, that means that as soon as I get any connection from the client, I can get an undef on that port during a pause or after input during the next cycle. So that was out.
I then set the port to block, and set the Timeout value, but it wouldn't time out for me at accept. Dunno why that is, I'm on *nix, so it should work. *shrug*
So, I set the thing to block, and after the accept I added:
$test=$data_port->peerhost();
if (not defined $test){close_data_port;}
That way, during any client pause, the connection is still open, so peerhost returns it's IP address. When the connection drops, that value goes undef and I call my exit sub.
Now, my population explosion is under control. Many Thanks!
Declarent | [reply] [d/l] |
Unfortunately, non-blocking IO isn't as simple as blocking IO. I'm not sure why you say that your sockets are "defaulted to non-blocking" simply by virtue of using IO::Socket::INET. To my knowledge, sockets created from this module are not automatically placed in a non-blocking state unless you explicitly ask for them that way.
To get around the fact that many of your non-blocking socket calls will immediately return (frequently with 'undef'), you should use IO::Select to detect when a socket has something for you, or when a socket is available to accept data. It's generally safe then to read from or write to a socket such that you won't block, and won't get 'undef' (unless it really means it).
Unfortunately this logic tends to add a lot of additional complexity to your code. Fortunately, much of this has already been encapsulated in some Perl modules, POE being the most noteworthy.
| [reply] |
For timeout on accept() you can also use the "Timeout => $second" option when creating your socket (IO::Socket::INET):
# create a socket with a 10 second timeout
my $server_socket = IO::Socket::INET->new(
LocalPort => 1234,
Timeout => 10 );
my $client_socket = $server_socket->accept();
if( not defined $client_socket ) {
print "Timeout ...\n";
} else {
print "Process request ...\n"
}
| [reply] [d/l] |
If you are on *nix based system you have alarm and $SIG{ALRM} (no alarm on Win32). I do not know if this would be the best solution - I have not done socket programming for 4 years.
grep
Just me, the boy and these two monks, no questions asked. |
| [reply] [d/l] |