2012-02-10 98 views
4

这是我当前的代码:标值误差(与IO ::插座)

#!/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,它会给我一个错误“在使用”strict refs“时,不能使用字符串(”1“)作为符号ref。

如果我再改变@header [$ i] = $ ;到$ he​​ader [$ i] = $;我也得到同样的错误。我怎样才能使这个脚本更好。

+1

什么行导致错误?另外,如果将'$ socket'作为新的'IO :: Socket :: INET'对象的创建不成功,你应该或者'死掉'或者移动到下一个参数。 – 2012-02-10 00:33:47

+2

@header [$ i]'不正确,即使将它改为正确的东西也不能解决错误。 – geoffspear 2012-02-10 00:35:22

+1

@Wooble - 很好。为什么总是应该启用'warnings'编译指示的另一个原因。 – 2012-02-10 00:38:08

回答

10

的问题是在你设置$socket方式:由于您使用的||运营商,其中有precedence高于=

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

,这种说法被解析为

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

如果new IO::Socket::INET返回一个错误值(如果连接失败),print将执行其retu价值(通常是1)将被分配到$socket。 当你再尝试使用$socket在声明的indirect object

print $socket "GET/HTTP/1.0\n\n"; 

的Perl注意到的价值1并不是真正的对象引用,并抛出你报告的错误。

如果你使用的||低优先级运营商,而不是or$socket值会一直undef,而不是1,并且你会收到错误信息会一直像Can't use an undefined value as a symbol reference ...。当然,这不会真的解决你的问题,但至少可以让它更容易诊断。

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

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 
} 
+0

+1好收获。 '' – TLP 2012-02-10 02:53:15

0

那不是简单的解决方案是使用低优先级的版本“或”具有比“=”低优先级?

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

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