This is my current code:
#!/usr/bin/perl -w
use strict;
require IO::Socket;
while (<>) {
chomp(my $host = $_);
my @header;
print "Connecting to: $host\n";
my $socket = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => 80,
Proto => 'tcp') || print "Could not connect: $!\n";
print "Connected.\n";
print $socket "GET / HTTP/1.0\n\n";
my $i = 0;
while (<$socket>) {
@header[$i] = $_;
$i++;
}
$i = 0;
print "--------------------------------------\n";
while ($i <= 8) {
print "@header[$i++]";
}
print "-------------------------------------\n";
print "Finished $host\n\n";
}
If while going through a list of IP's, and a host is down, instead of continuing onto the next IP, it will give me an error "Can't use string ("1") as a symbol ref while "strict refs" in use".
If I then change @header[$i] = $; to $header[$i] = $; I also get the same error. How can I make this script better.
The problem is in the way you set $socket
:
my $socket = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => 80,
Proto => 'tcp') || print "Could not connect: $!\n";
Since you're using the ||
operator, which has higher precedence than =
, this statement is parsed as
my $socket = (new IO::Socket::INET(...) || print ...);
If new IO::Socket::INET
returns a false value (as it does if the connection fails), the print
will be executed and its return value (which is normally 1
) will be assigned to $socket
.
When you then try to use $socket
as an indirect object in the statement:
print $socket "GET / HTTP/1.0\n\n";
Perl notices that the value 1
is not actually an object reference and throws the error you reported.
If you'd used the low-precedence operator or
instead of ||
, the value of $socket
would've been undef
instead of 1
, and the error message you'd have received would've been something like Can't use an undefined value as a symbol reference ...
. Of course, this wouldn't have actually fixed your problem, but at least it might've made it easier to diagnose.
To actually fix the problem, you need to fix your code so that you won't keep executing the rest of the loop body if the connection fails. One way to do that would be like this:
my $socket = new IO::Socket::INET(
PeerAddr => $host,
PeerPort => 80,
Proto => 'tcp');
unless ($socket) {
print "Could not connect: $!\n";
next; # skip the rest of the loop
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With