Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Problem in IO::Socket syntax?

by c (Hermit)
on Mar 30, 2002 at 22:33 UTC ( [id://155509]=perlquestion: print w/replies, xml ) Need Help??

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

I've written a short script that checks to see if a remote server is listening on a specific TCP port. Its in the early stages, so some error checking needs to be built in. For now though, I'm confused by an error that I am getting when I test it using localhost as the guinea pig.

1 #!/usr/bin/perl -w 2 3 # $Id:$ 4 5 # check to see if server is listening on a tcp port 6 7 use strict; 8 use IO::Socket; 9 10 my @servers = qw(localhost); 11 12 my %ports = ( 13 telnet => "23", 14 smtp => "25", 15 pop3 => "110", 16 named => "53", 17 http => "80", 18 https => "443", 19 ); 20 21 my $proto = "tcp"; 22 my $disco = 0; 23 24 for my $host(@servers) { 25 26 my $ip = gethostbyname($host); 27 my $ip_addr = inet_ntoa($ip); 28 29 for my $service(keys %ports) { 30 31 my $disco = 0; 32 33 my $checkport = IO::Socket::INET->new( 34 PeerAddr => "$ip_addr", 35 PeerPort => "$ports{$service}", 36 Proto => "$proto", 37 Timeout => '0') 38 or $disco = "1"; 39 40 print "$host FAILED to repond on $service $ports{service}\ +n" 41 if $disco; 42 43 close $checkport; 44 45 } 46 }

When I run the script, I get:

Use of uninitialized value in concatenation (.) at ./chkport.pl line 4 +0. localhost FAILED to repond on telnet Can't use an undefined value as a symbol reference at ./chkport.pl lin +e 43.

i'm staring at the print statement and the close statement. Both seem to be correct to the best that I can tell. Your input is well appreciated as always.

humbly -c

Replies are listed 'Best First'.
Re: Problem in IO::Socket syntax?
by Ryszard (Priest) on Mar 30, 2002 at 23:03 UTC
    print "$host FAILED to repond on $service $ports{service}\n"

    becomes

    print "$host FAILED to respond on $service $ports{$service}\n"

    Other than that, do you have a firewall on localhost that may prevent connections?

      Thanks for correcting my poor grammar ;-) To answer your question and the previous, there is no local firewall, and I intentionally included telnet in the list of services because I know that it is not enabled on this host. Really just testing to make certain I get the output I desire when a service is down.
      I just don't understand the error that was being spit out. I don't see the concantenation that its referring to.

      -c

        If i understand correctly (and I havent run your code) you should be using the variable $service in your hash, rather than the hard reference service.

        Your hash %ports has no key of service.

Re: Problem in IO::Socket syntax?
by lestrrat (Deacon) on Mar 30, 2002 at 22:52 UTC

    The only thing I can say is that while there are a few things that I would do differently and that there's a small typo on line 40, your code works for me. Are you absolutely sure that you can access the telnet port on that machine that you're accessing?

      telnet is not enabled on the host i am testing on, so the output of telnet failing isnt what throws me. i dont see where the error complaining about the concatenation is coming from however.

      thanks -c

        Oh.

        I understand that you were probably frustrated not know where on earth the word "concatnation" would come out of your code, but you didn't say that that was your problem. Wouldn't you agree it's really hard to tell what you were asking? ;)

        Anyway, I think Ryszard got the answer correctly... basically, embedding variables in string implicitly invokes the concat op, so your line 40 is equivalent of:

        print $host . " FAILEd to repond on " . $service . " " . $ports{ se +rvice } . "\n";

        So you see that if $port{ service } was undefined, you would get a concatnation warning. If you're interested, check out the output of perl -MO=Terse yourscript.pl

Re: Problem in IO::Socket syntax?
by flocto (Pilgrim) on Mar 31, 2002 at 00:54 UTC
    Well, AFAIK IO::Socket returns undef upon failure, and will have a hard time closing an undefined variable. In this case you should change your code to:
    if ($disco) { print "$host FAILED to respond on $service $ports{$service}\n"; } else { close $checkport; }
    I couldn't find IO::Socket's return value when failing in it's documentation, but that it calls connect(), and this returns false when failing. I can't imagine that it (IO::Socket) would return a socket even when failing to open one, so my guess is that this is your mistake. I don't use IO::Socket all that often, so I might be wrong here.. Hope this helps ;)

    -octo-

      And when it fails, please also report why it failed. How to find out why it failed varies by module, but for IO::Socket, I'm pretty sure it is the common $! that you want to report in the error message.

              - tye (but my friends call me "Tye")
Re: Problem in IO::Socket syntax?
by DigitalKitty (Parson) on Mar 31, 2002 at 18:13 UTC
    Hi.

    I'm glad the problem was solved but just for reference, if you are using a linux machine ( w/ 2.2 kernel ), you can enable or disable the telnet daemon by editing your inetd.conf file. Just remove the '#' sign that appears in front of the name of the service ( telnet ). Then restart the service and you should be able to telnet to your local machine. If you are using a 2.4 kernel, the file is called xinetd. It's more secure than the 2.2 implementation but serves the same purpose essentially.

    Thanks,

    -DigitalKitty

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://155509]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (7)
As of 2024-04-24 20:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found