Ошибки скалярного значения (с IO :: Socket) - PullRequest
4 голосов
/ 10 февраля 2012

Это мой текущий код:

#!/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-адрес выдаст ошибку «Can»t использовать строку («1») в качестве символа ref, тогда как используются «строгие ссылки».

Если я тогда изменю @header [$ i] = $ ;в заголовок $ [$ i] = $ ;Я также получаю ту же ошибку.Как я могу сделать этот скрипт лучше.

Ответы [ 2 ]

10 голосов
/ 10 февраля 2012

Проблема в том, как вы установили $socket:

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 будет выполнено и будет возвращено его возвращаемое значение (обычно 1) $socket. Когда вы затем попытаетесь использовать $socket в качестве косвенного объекта в выражении:

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 голосов
/ 15 ноября 2012

Не будет ли простым решением использовать версию с более низким приоритетом 'или', которая имеет более низкий приоритет, чем '='?

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

Фактически операторы 'or' и 'xor' имеют наименьший приоритет операторов (см. Perlop).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...