Welcome to WebmasterWorld Guest from 184.72.177.182

Forum Moderators: coopster & jatar k & phranque

Message Too Old, No Replies

IO::Socket::INET and timeout

doesn't work

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

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 18, 2003
posts:1925
votes: 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?

4:37 pm on July 18, 2003 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:July 6, 2000
posts:904
votes: 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?

4:42 pm on July 18, 2003 (gmt 0)

Administrator from US 

WebmasterWorld Administrator brett_tabke is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Sept 21, 1999
posts:38048
votes: 12


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.

4:52 pm on July 18, 2003 (gmt 0)

Senior Member

WebmasterWorld Senior Member littleman is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:June 17, 2000
posts:2924
votes: 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";

6:32 pm on July 18, 2003 (gmt 0)

Junior Member

10+ Year Member

joined:May 3, 2003
posts:159
votes: 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.

7:03 pm on July 18, 2003 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 18, 2003
posts:1925
votes: 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.

1:23 pm on July 20, 2003 (gmt 0)

Junior Member

10+ Year Member

joined:May 3, 2003
posts:159
votes: 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'
2:20 am on July 22, 2003 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:June 18, 2003
posts:1925
votes: 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.
6:09 pm on July 22, 2003 (gmt 0)

Senior Member

WebmasterWorld Senior Member littleman is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:June 17, 2000
posts:2924
votes: 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"

11:45 pm on July 23, 2003 (gmt 0)

New User

10+ Year Member

joined:Aug 12, 2002
posts:8
votes: 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.