homepage Welcome to WebmasterWorld Guest from 54.196.168.78
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Subscribe to WebmasterWorld
Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
Forum Library, Charter, Moderators: coopster & jatar k & phranque

Perl Server Side CGI Scripting Forum

    
IO::Socket::INET and timeout
doesn't work
moltar




msg:445027
 3:16 pm on Jul 17, 2003 (gmt 0)

Tried using timeout option in the IO::Socket::INET module and it doesn't work. I looked in the source code of the INET.pm and the whole timeout option was commented out.

Is there a way to make it work?

 

sugarkane




msg:445028
 4:37 pm on Jul 18, 2003 (gmt 0)

> Is there a way to make it work?

Remove the comment marks in the package source? ;)

The commenting out seems strange - what version of IO::Socket are you using?

Brett_Tabke




msg:445029
 4:42 pm on Jul 18, 2003 (gmt 0)

I spent over an hour yesterday trying to figure out an answer to this question. I tried removing the commenting too, but even under linux it didn't make a difference.

I thought at first the commenting was for the winders version only, but it doesn't appear to be.

littleman




msg:445030
 4:52 pm on Jul 18, 2003 (gmt 0)

On a Debian system I was using this routine without any hanging.

$remote = IO::Socket::INET->new(
Proto => "tcp",
Timeout => "5",
PeerAddr => $host,
PeerPort => "http($port)",
);

my $content;
if ($remote) {
$remote->autoflush(1);
print ">>flushed>>";
print $remote "GET $document HTTP/1.1" . $EOL;
print $remote "Host: $host" . $EOL;
print $remote
'User-Agent: Mozilla/5.0 Galeon/1.2.6 (X11; Linux i686; U;) Gecko/20020913 Debian/1.2.6-2'
. $EOL;
print $remote
'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1'
. $EOL;
print $remote "Connection: close" . $EOL;
print $remote $EOL;
print $remote $EOL;
print " asked for $document..";

while (<$remote>) {
$content .= $_;

#print
}

close $remote;
print "closed connection";

Storyteller




msg:445031
 6:32 pm on Jul 18, 2003 (gmt 0)

I've struggled with this a while ago and could not make it work. I don't remember exactly what the source of the problem was (I've found a document that explained it), but it was rather low-level and only present on certain OS'es.

I finally reverted to a workaround using alarm(), which worked fine for me.

BTW, timeout funtion in LWP does work, so a better answer may be hidden in the LWP source.

moltar




msg:445032
 7:03 pm on Jul 18, 2003 (gmt 0)

sugarkane:
I am using v1.25. The newest one is v1.26, but Timeout is still commented out.

Brett_Tabke:
Yes, I've tried commenting out and playing around with it, in both Windows and Linux, and also have no luck! :(

littleman:
Yes, there is no hanging, if you pass Timeout option to the module, it just doesn't do anything. Did you ever try to timeout on purpose. Did it work? Try to connect to a host that does not exist. It will most likely hang. Unless the version of the module on Debian is somewhat different from RedHat or Windowz.

Storyteller:
Would you want to sticky me or post it here an example of alarm() code?

Thanks to everybody.

P.S. I also emailed this question to the developer, still waiting for reply.

Storyteller




msg:445033
 1:23 pm on Jul 20, 2003 (gmt 0)

moltar, I replaced that code with an LWP call long ago. I'm almost certain I got the idea from O'Reilly's "Perl Cookbook" accompanying sources. May I suggest googling on 'perl alarm timeout socket'

moltar




msg:445034
 2:20 am on Jul 22, 2003 (gmt 0)

Storyteller: the thing is that this is not for HTTP requests. It's for WHOIS requests and LWP doesn't allow that. Internic server keeps timing out all the time and my script gets stuck and never ends.

littleman




msg:445035
 6:09 pm on Jul 22, 2003 (gmt 0)

I can't get this to hang at all no mater what address I feed it...tested on a Debian box.

use IO::Socket;
$host = "whatever.whatever";
my $EOL = "\015\012"; ## a CR LF pair for the server
$remote = IO::Socket::INET->new(
Proto => "tcp",
Timeout => "5",
PeerAddr => $host,
PeerPort => "http(80)",
);

my $content;
if ($remote) {
$remote->autoflush(1);
print ">>flushed>>";
print $remote "GET $document HTTP/1.1" . $EOL;
print $remote "Host: $host" . $EOL;
print $remote
'User-Agent: Mozilla/5.0'
. $EOL;
print $remote
'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1'
. $EOL;
print $remote "Connection: close" . $EOL;
print $remote $EOL;
print $remote $EOL;
print " asked for $document..";

while (<$remote>) {
$content .= $_;

print
}
}
close $remote;
print "closed connection"

SwissGuy




msg:445036
 11:45 pm on Jul 23, 2003 (gmt 0)

As far as I know, two things are to be kept in mind when using the timeout function provided by IO::Socket (though I have no idea why it's commented out):

1. The module only checks for a timeout during the socket connect handshake, not for reads or writes! It does this by setting the socket to non-blocking (via IO::Select) during connect.
2. If you set Timeout, another module - IO::Select - is called in which adds to the overhead except if you already utilize it in your application.

If you need a fine-tuned solution offering the most flexibility (timing, autoflush, non-blocking, etc.) or a portable timeout solution working both on UNIX and WINDOWS, you'd have to use your own "select/vec" calls on each socket operation - and probably also handle the socket methods yourself (via "use Socket").

Else, I often use the system alarm call wrapped in an eval of the entire socket routine. I.e., using IO::Socket:

eval {
local $SIG{ALRM} = sub { die 'Timed Out'; };
alarm 3;
my $sock = IO::Socket::INET->new(
PeerAddr => inet_ntoa( gethostbyname($host) ),
PeerPort => 'whois',
Proto => 'tcp',
## Timeout => ,
);
$sock->autoflush;
print $sock "$qry\015\012";
undef $/; $data = <$sock>; $/ = "\n";
alarm 0;
};
alarm 0; # race condition protection
return "Error: Timeout." if ( $@ && $@ =~ /Timed Out/ );
return "Error: Eval corrupted: $@" if $@;

Just remember to not mix sleep with alarm calls when running on Linux.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved