macx666 has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks, I am having problems with a script I wrote. For you're ease, I'll break the query down to the following table of contents (hopefully the anchors work, sorry if they don't):
  1. Task at hand
  2. Problems encountered
  3. Code

Task at hand


1. Have a set of servers to connect to and:
2. Have a list of different ports (per server)
3. Attempt to connect to each port listed under each server
4. Report attempted connect as either the port being up, or down
----

Problems encountered


The results I got back are:
Starting Ping System Service at arbornet.org on port: ARRAY(0x804b424) is down Can't use an undefined value as a symbol reference at ./new_ping.pl li +ne 47.
When I am not using warnings or strict, line 47 does not error, and when I am using a single port (80 possibly), it does not error. Mind you, I modify it so that it does not try to do the foreach loop on the ports in the latter possibility...
----

Code


#!/usr/local/bin/perl use IO::Socket; use strict; use warnings; # default port my $pt = "8080"; my $inactive; my $call; my $server_ip; my @remote_server; my @remote_port; $remote_server[0] = "arbornet.org"; $remote_port[0][0] = "21"; $remote_port[0][1] = "23"; $remote_port[0][2] = "80"; #$remote_server[1] = "slashdot.org"; #$remote_port[1][0] = "80"; #$remote_server[2] = "apple.com"; #$remote_port[2][0] = "80"; #$remote_server[3] = "yahoo.com"; #$remote_port[3][0] = "80"; my $i = 0; print "Starting Ping System\n"; foreach $server_ip (@remote_server){ print "\nService at $server_ip on port:\n"; foreach $pt ($remote_port[$i]){ $inactive = 0; $call = IO::Socket::INET-> new ( PeerAddr => "$server_ip", PeerPort => "$pt", Proto => 'tcp', Timeout => '5', ) or $inactive = 1; if (!($inactive)) { print " $pt is up\n"; } else { print " $pt is down\n"; } close $call; } }

Replies are listed 'Best First'.
Re: Help with multidimensional arrays and IO::Socket
by Abigail-II (Bishop) on Aug 29, 2002 at 17:27 UTC
    You want:
    foreach $pt (@{$remote_port [$i]}) {
    You should also increment $i in your loop.

    However, I would note store the data over two arrays. I'd keep a hash, like this:

    my %data = ( 'arbornet.org' => [21, 23, 80], 'slashdot.org' => [80], 'apple.com' => [80], 'yahoo.com' => [80], );
    and iterate with each over the hash.

    Abigail

Re: Help with multidimensional arrays and IO::Socket
by fglock (Vicar) on Aug 29, 2002 at 17:29 UTC

    $remote_port[$i] is an array reference. To get each port you should "foreach" $pt contents:

    foreach $port (@$pt) { ... }
Re: Help with multidimensional arrays and IO::Socket
by sauoq (Abbot) on Aug 29, 2002 at 20:02 UTC
    if (!($inactive)) { print " $pt is up\n"; } else { print " $pt is down\n"; } close $call;

    Leaving style out of it, the quick fix is to put close $call; inside your if (! ($inactive)) clause as you only want to close it if it isn't inactive.

    Taking style into account, you don't need your $inactive variable at all and it amounts to a double negative in your if clause making it difficult to read. Why not just use $call itself?

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Help with multidimensional arrays and IO::Socket
by macx666 (Beadle) on Aug 29, 2002 at 18:17 UTC
    Both suggestions are great for the port issue, but what is still a problem is the "undefined value as a symbol reference" when a port fails to respond. As soon as a port is registered as down, this script fails to continue...
      $call = ... or $inactive = 1;

      makes $call = 1 if the port is down. Then you have "close 1;" later. This might be the problem.