sockaddr_in() timeout or asynchone call ?

A

Asterbing

Hello,

Is it possible to do that a code like the one described on the chapter
42.6.2 called "WebGet Client" on the Perl manual, be not a locking point
for the rest of the script ?

Effectively, the sockaddr_in() freeze the script if the remote host is
not available.

Is there a way to reduce the timeout or, better, to do that this call be
asynchroneous (don't taliking about waiting of the response since in the
first case I've to treat, this GET response isn't necessary for the rest
of the script - the matter is just to launch a remote cgi which will
live its life by itself).
 
U

Uri Guttman

JG> The choice to prevent a program blocking on I/O usually involves
JG> either non-blocking I/O (polling) or asynchronous I/O (e.g, the
JG> select statement or forking/threading). Both have their
JG> complications.

you are conflating several things there. the blocking nature of the
socket has nothing to do with whether you use select on it. and select
has nothing to do with forking/threads. and async i/o can means using
the OS's async i/o ops or an event loops that supports it or even using
threads. so you can pretty much mix and match all of those things and
you don't have an either/or situation.

but i agree with your main assessment, sockaddr_in just does some simple
IP address munging and should never block. the OP is confused or
misunderstood something.

uri
 
A

Asterbing

Which Perl manual? I have several. None of them come close to having 42
Chapters. Does your Perl manual have a title? An author? A publisher?
An edition number? Maybe it would be easier if you just posted the
code.

Of course. Here is the doc : <http://perl.enstimac.fr/perl-all-fr-
pdf.pdf> and here is the code I'm using in a sub :

StatsRelay()
{
use IO::Socket;

my $host = "www.domain.com";
my $path = "/cgi-bin/stats.cgi?a=2&t=12&z=27&rz=102";
my $port = 8080;

if ($host eq "" or $path eq ""){ return(0);}
my $iadr = inet_aton($host) || return(0);
my $padr = sockaddr_in($port, $iadr);
my $proto = getprotobyname('tcp');

socket(hpSOCK, PF_INET, SOCK_STREAM, $proto) || return(0);
if(!connect(hpSOCK, $padr)){return(0);}

hpSOCK->autoflush();
print hpSOCK "GET $path HTTP/1.1\015\012";
print hpSOCK "Host: $host\015\012\015\012";

...

close(hpSOCK);
return(1);
}
Curious. The sockaddr_in function (of the Socket module) packs and
unpacks interaddress protocol addresses. It does no input or output. It
is hard to see how it could possibly "freeze". Maybe it is something
else in your program that is blocking. Of course, it is hard to tell
without seeing your program.

I'm calling the sub above like this :

$rc= StatsRelay();

Maybe I could remove the $rc analysis since this call is done sevral
times a hour and just some are useful per day (security). Don't know if
it would change something.

However to point the sockaddr_in() fct, I've commented out the rest
below it and deconnected the LAN from Internet.
The choice to prevent a program blocking on I/O usually involves either
non-blocking I/O (polling) or asynchronous I/O (e.g, the select
statement or forking/threading). Both have their complications.

See 'perldoc -f select' or 'perldoc IO::Select' (your platform may
affect your results.)

OK, thanks Jim, a little bit afraid of your "both have complications"
but I'll take a look to these parts of perldoc.
 
A

Asterbing

you are conflating several things there. the blocking nature of the
socket has nothing to do with whether you use select on it. and select
has nothing to do with forking/threads. and async i/o can means using
the OS's async i/o ops or an event loops that supports it or even using
threads. so you can pretty much mix and match all of those things and
you don't have an either/or situation.

However I've to do that the code below work both under Win32 and FreeBSD
and be not a hanging point (remembering I don't have to wait for get
response for the rest of the script : maybe an important point !!!) :

StatsRelay()
{
use IO::Socket;

my $host = "www.domain.com";
my $path = "/cgi-bin/stats.cgi?a=2&t=12&z=27&rz=102";
my $port = 8080;

if ($host eq "" or $path eq ""){ return(0);}
my $iadr = inet_aton($host) || return(0);
my $padr = sockaddr_in($port, $iadr);
my $proto = getprotobyname('tcp');

socket(hpSOCK, PF_INET, SOCK_STREAM, $proto) || return(0);
if(!connect(hpSOCK, $padr)){return(0);}

hpSOCK->autoflush();
print hpSOCK "GET $path HTTP/1.1\015\012";
print hpSOCK "Host: $host\015\012\015\012";

...

close(hpSOCK);
return(1);
}
but i agree with your main assessment, sockaddr_in just does some simple
IP address munging and should never block. the OP is confused or
misunderstood something.

Hum, with Jim, you're starting to do I'm wondering if I've well pointing
the responsible line... Maybe a wrong debug, maybe too tired... Well,
imagine it's not sockaddr_in, but something later (socket(), connect
())... The objectif remains the same : do this StatsRelay be not a
blocking point even if the target host or uri (not you, Uri ;-)) is not
available :(

Thanks for your help, Uri and Jim.
 
U

Uri Guttman

A> However I've to do that the code below work both under Win32 and FreeBSD
A> and be not a hanging point (remembering I don't have to wait for get
A> response for the rest of the script : maybe an important point !!!) :

A> StatsRelay()
A> {
A> use IO::Socket;

why are you using that module but not even using it to connect? or why
aren't you using LWP for the web page fetch? the number of possible
problems you avoid will amaze you.


A> my $host = "www.domain.com";
A> my $path = "/cgi-bin/stats.cgi?a=2&t=12&z=27&rz=102";
A> my $port = 8080;

A> if ($host eq "" or $path eq ""){ return(0);}
A> my $iadr = inet_aton($host) || return(0);
A> my $padr = sockaddr_in($port, $iadr);
A> my $proto = getprotobyname('tcp');

A> socket(hpSOCK, PF_INET, SOCK_STREAM, $proto) || return(0);


A> if(!connect(hpSOCK, $padr)){return(0);}

my $sock = IO::Socket::INET->new( "$host:$port" ) ;

isn't that much nicer?

A> print hpSOCK "GET $path HTTP/1.1\015\012";
A> print hpSOCK "Host: $host\015\012\015\012";

more code you shouldn't be writing.

A> Hum, with Jim, you're starting to do I'm wondering if I've well pointing
A> the responsible line... Maybe a wrong debug, maybe too tired... Well,
A> imagine it's not sockaddr_in, but something later (socket(), connect
A> ())... The objectif remains the same : do this StatsRelay be not a
A> blocking point even if the target host or uri (not you, Uri ;-)) is not
A> available :(

if you would read the docs on those calls you can see what they do and
if they would block. but why you are writing it at such a low level is
beyond me. just use LWP::Simple and it is one call. something like this
(untested) :

use LWP::Simple ;

my $page = get( "http://$host:$port$path" );

even nicer than before!

uri
 
A

Asterbing

That's not a sub, that's a syntax error.

OK, effectively a typo, but it doesn't change the sense of the question.

sub StatsRelay
{
# as said in previous post
}
 
A

Asterbing

A> use IO::Socket;

why are you using that module but not even using it to connect? or why
aren't you using LWP for the web page fetch? the number of possible
problems you avoid will amaze you.

Don't know, it's code found on the net. So, since I'm new in Perl
(you've noticed my mistake about sub syntax), could you tell me the
right way using IO::Socket or any code using only what provided with all
Perl 5.x.

Well, the second part of the question is simple : I don't want (since
config about target servers out of my own decision) to use something
else than the Perl 5.x stock modules.
my $sock = IO::Socket::INET->new( "$host:$port" ) ;

Is that the only line to change in the sub ?
A> print hpSOCK "GET $path HTTP/1.1\015\012";
A> print hpSOCK "Host: $host\015\012\015\012";

more code you shouldn't be writing.

Pardon ?
 
U

Uri Guttman

A> In article <[email protected]>, (e-mail address removed)
A> says...
A> use IO::Socket;
A> Don't know, it's code found on the net. So, since I'm new in Perl
A> (you've noticed my mistake about sub syntax), could you tell me the
A> right way using IO::Socket or any code using only what provided with all
A> Perl 5.x.

don't use most perl code you find on the net. too much of it sucks and
is for kiddies.

A> Well, the second part of the question is simple : I don't want (since
A> config about target servers out of my own decision) to use something
A> else than the Perl 5.x stock modules.

LWP (the perl web client modules) is now in the core distribution. but
that still means making sure your servers have a recent perl. if you
can't load modules (which you can as a normal user so that is not a
valid excuse) then how would you load a recent perl?

A> Is that the only line to change in the sub ?

no. it replaces all the crappy socket code you copied. another point is
never copy and use code unless you understand it.

A> print hpSOCK "GET $path HTTP/1.1\015\012";
A> print hpSOCK "Host: $host\015\012\015\012";
A> Pardon ?

all that code is handled by LWP so use it instead of the crap you
copied.

uri
 
A

Asterbing

don't use most perl code you find on the net. too much of it sucks and
is for kiddies.

OK, daddy ;)
LWP (the perl web client modules) is now in the core distribution. but
that still means making sure your servers have a recent perl. if you
can't load modules (which you can as a normal user so that is not a
valid excuse) then how would you load a recent perl?

I will have to install the script on several servers, we the less upt to
date being with Perl 5.00503 under FreeBSD
A> Is that the only line to change in the sub ?

no. it replaces all the crappy socket code you copied. another point is
Understood

A> print hpSOCK "GET $path HTTP/1.1\015\012";
A> print hpSOCK "Host: $host\015\012\015\012";

all that code is handled by LWP so use it instead of the crap you
copied.

Yes, but I don't want to consider the GET return (neither header nor
server response content). My subject is just to push url parameters
toward the remote cgi !

Well, someone in fr.comp.lang.perl suggest me to go through fork like
this for the purpose to do thing be no-blocking for the rest of the
script (as I wish) :

my $child = fork;
die "fork: $!\n" unless defined $child;
return if $child;

What do you mean about this way ? It's a little bit obscur for me and
don't really see how to embed a call to my sub this way...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top