Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Timing-out network clients?

by pascaldee (Acolyte)
on Dec 02, 2007 at 02:53 UTC ( [id://654378]=perlquestion: print w/replies, xml ) Need Help??

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

A typical network server would want to time out slow/idle network clients to keep the maximum number of connection slots available. Think Apache's TimeOut setting or qmail's timeoutconnect and timeoutremote. So far I can't figure out how to do this in Perl. Setting IO::Socket's timeout doesn't seem to do anything. Do I have to resort to alarm()?

#!/usr/bin/perl -w use strict; use Carp; use Net::SMTP::Server; use Net::SMTP::Server::Client; my $server = new Net::SMTP::Server('localhost', 2525) or croak; while (my $conn = $server->accept()) { next if fork() == 0; $conn->timeout(30); my $client = new Net::SMTP::Server::Client($conn) or croak; $client->process or next; }

Replies are listed 'Best First'.
Re: Timing-out network clients?
by TOD (Friar) on Dec 02, 2007 at 04:51 UTC
    i cannot find our where you got this timeout() method from. it's neither part of the Client packet, nor of any of the modules you require. the 'Timeout' value is an argument to the constructor of an IO::Socket::INET instance, which is basically all the Net::SMTP::Server package is wrapped around. the pod from IO::Socket::INET tells us that it stands "for various operations", whatever this means. however, all of the perl socket API in the end results in calls to system functions (socket(), accept(), listen() etc.), and none of these system functions requires a timeout argument.
    --------------------------------
    masses are the opiate for religion.
Re: Timing-out network clients?
by erroneousBollock (Curate) on Dec 03, 2007 at 02:12 UTC
    IO::Socket::INET's timeout method (or the Timeout hash-param to the constructor) won't do what you want here. That timeout value corresponds to how long the socket should wait for acknowledgment from the peer when it has sent data (or is trying to connect).

    You definitely do need some sort of "global timer". You're forking, so it's probably as simple as:

    1. recording the PID of the child in a hash, along with the start time
    2. noting when the child process should no longer be around,
    3. sending the KILL signal to the child process.
    To set up the timer, you'll either need to use alarm, or switch to a non-blocking form of $server->accept.
    I recommend putting the listening socket into an IO::Select object, then adding calls to Timer::HiRes::usleep in your while loop.

    -David

      Thanks for the suggestion. I prefer not simply limiting the maximum age for a child, since children need different time according to their connection speed and amount of data to send. I want to set timeout for every read from the client. So I guess I'll try to look at a select()-based approach.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://654378]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2024-04-26 07:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found