dru145 has asked for the wisdom of the Perl Monks concerning the following question:
Monks,
This one is driving me crazy. I can not figure out why when i put the ip's into an array it's not working corrctly, but if I test them separatly in a scalar it works. When I say it's not working correctly, I mean it's showing both ips as being up, even when one is down. If I assign $ip to the actual ip address, then it works. Can anyone let me know if they see something wrong with the below code?
#!/usr/bin/perl -w
use strict;
use IO::Socket::INET;
my @host = ('192.168.1.3', '192.168.46.2');
my $port = '22';
my ($connected);
foreach (@host){
check($_);
}
sub check {
my $ip = $_[0];
my $sock = IO::Socket::INET->new(PeerAddr => $ip,
PeerPort => $port,
Proto => 'tcp',
timeout => '10')
and $connected = 1;
print "$ip is listening on port $port\n" if $connected;
print "$ip is NOT listening on port $port.\n" unless $connected;
}
Thanks,
Dru
Another satisfied monk.
Re: Array Woes
by thelenm (Vicar) on Dec 12, 2002 at 17:55 UTC
|
The main problem I see is that you never reset the value of $connected between calls to check. The scope of $connected should really be limited to the subroutine, not the whole program. Move the my $connected line inside the subroutine, and that may solve your problem.
-- Mike
--
just,my${.02} | [reply] [d/l] [select] |
Re: Array Woes
by Abigail-II (Bishop) on Dec 12, 2002 at 17:59 UTC
|
You never reset $connected. Once it's set to 1,
it never becomes false again. Limit the scope of your variables.
If you make $connected lexical in the check
sub, you might see better results.
Abigail | [reply] [d/l] [select] |
Re: Using 'and'
by tadman (Prior) on Dec 12, 2002 at 19:32 UTC
|
Quick re-write which tries to straighten out that problem others have described:
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::INET;
my @host = qw[ 192.168.1.3 192.168.46.2 ];
my $port = 22;
foreach (@host)
{
check($_, $port);
}
sub check {
my ($ip, $port) = @_;
my $sock = IO::Socket::INET->new(
PeerAddr => $ip,
PeerPort => $port,
Proto => 'tcp',
timeout => 10,
);
if ($sock) {
print "$ip is listening on port $port\n";
return 1;
}
print "$ip is NOT listening on port $port.\n";
return;
}
Since $sock is either defined or not, there's no real need for a $connected variable. Likewise, in the interest of reducing global variable propagation, it's better to pass $port explicitly.
You also don't need to quote numbers. Not that it's a huge difference, but it looks odd. | [reply] [d/l] |
|
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::INET;
my @host = qw[ 192.168.1.3 192.168.46.2 ];
my $port = 22;
foreach (@host)
{
check($_, $port);
}
sub check {
my ($ip, $port) = @_;
print
(
my $sock = IO::Socket::INET->new(
PeerAddr => $ip,
PeerPort => $port,
Proto => 'tcp',
timeout => 10,
)
? "$ip is listening on port $port\n"
: "$ip is NOT listening on port $port.\n"
)
}
But then again, I'm a sucker for the ternary operator.
LAI
:eof | [reply] [d/l] |
|
I think that edges into obfuscation territory. What about this?
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket::INET;
my @host = qw[ 192.168.1.3 192.168.46.2 ];
my $port = 22;
foreach (@host)
{
check($_, $port);
}
sub can_connect
{
my ($ip, $port) = @_;
return ! !IO::Socket::INET->new(
PeerAddr => $ip,
PeerPort => $port,
Proto => 'tcp',
timeout => 10,
);
}
sub check
{
my ($ip, $port) = @_;
my $can_connect = can_connect($ip,$port);
print "$ip is ";
print "NOT" unless ($can_connect);
print " listening on port $port\n";
return $can_connect;
}
sub check_variation
{
my $can_connect = can_connect(@_);
print "$ip is ";
print "NOT" unless ($can_connect);
print " listening on port $port\n";
return $can_connect;
}
| [reply] [d/l] |
|
|
|
|
> But then again, I'm a sucker for the ternary operator.
...I like that. I must confess to the same weakness.
...All the world looks like -well- all the world,
when your hammer is Perl.
---v
| [reply] |
Re: Array Woes
by pg (Canon) on Dec 12, 2002 at 18:09 UTC
|
The problem is that 'and'. If you failed to create the socket, undef returned, and there is no need for perl to access whatever after that 'and'. So $connect is not set to what you want. | [reply] |
|
|