标量值错误(使用IO :: Socket)

时间:2012-02-10 00:30:51

标签: perl

这是我目前的代码:

#!/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";
}

如果在浏览IP列表时,主机已关闭,而不是继续使用下一个IP,它将给出一个错误“不能使用字符串(”1“)作为符号引用,而”严格refs“in use”。

如果我然后更改@header [$ i] = $ ;到$ he​​ader [$ i] = $ ;我也得到了同样的错误。如何使这个脚本更好。

2 个答案:

答案 0 :(得分:10)

问题在于您设置$socket的方式:

my $socket = new IO::Socket::INET(
        PeerAddr => $host,
        PeerPort => 80,
        Proto => 'tcp') || print "Could not connect: $!\n";

由于您使用的||运算符的precedence高于=,因此该语句被解析为

my $socket = (new IO::Socket::INET(...) || print ...);

如果new IO::Socket::INET返回false值(就像连接失败时那样),print将执行返回值(通常为{{1} }})将被分配给1。 然后,当您尝试在语句中使用$socket作为indirect object时:

$socket

Perl注意到值print $socket "GET / HTTP/1.0\n\n"; 实际上不是对象引用并抛出您报告的错误。

如果您使用了低优先级运算符1而不是or,那么||的值将是$socket而不是undef ,你收到的错误信息就像是1。当然,这实际上并没有解决你的问题,但至少它可能会让你更容易诊断。

要真正解决问题,您需要修复代码,以便在连接失败时不会继续执行循环体的其余部分。一种方法是这样的:

Can't use an undefined value as a symbol reference ...

答案 1 :(得分:0)

简单的解决方案难道不是使用优先级低于'='的较低优先级版本'或'吗?

my $socket = new IO::Socket::INET(
    PeerAddr => $host,
    PeerPort => 80,
    Proto => 'tcp')
        or print "Could not connect: $!\n";

实际上,运算符'或'和'xor'具有最低的运算符优先级(参见perlop)。