Hello,

I'm trying to create a small TCP server with perl. I have a small Java app on my blackberry that sends data to the server. It's simple data, just an IP address, a colon, then a number. The server then takes that information, looks up a switch's actual port name (i.e. FastEthernet0/2) from a hash, and SSH's to a switch and applies some commands for me.

I've gotten the basic functionality to work. If a connection comes in and calls a port that's not defined in the hash, it returns an error. If a connection comes in that is not formatted properly, it ignores it. If a connection comes in that is formatted correctly, it connects and enters the commands.

The problem is that when a good connection comes in, the script works its SSH magic and then crashes with the following error Can't call method "recv" on an undefined value at udplisten802.pl line 44 (Yes, the script is called UDPlisten when I'm using TCP. I started out trying to use UDP but found out i couldn't tunnel UDP through my BES server, so i switched it and never renamed :) )

It only has issues if it has to SSH to the device. I put some print statements in to see where it gets before it dies. It seems its going back as far as it needs to, but when the code reads $client=$sock->accept();, it doesn't seem to actual let the socket acccept the connection. I've tried putting in a 2nd $client=$socket->accept(); right after the first, but that made it so that it only reacted to every other connection I made.

I've quite confused why it's not behaving. If someone could take a look, it'd be greatly appreciated. I will post the script as well as another script I made for generating test traffic. Please go easy on me, I'm a fairly novice Perl guy, but I'm trying to learn. Thanks!!

udplisten.pl - the actual "Server" script.

use IO::Socket; use Net::Appliance::Session; use strict; use warnings; my ($sock,$LOCALPORT,$MAXLEN,$newmsg,$USER,$PASSWORD,$FILENAME,%PORTHA +SH,$client,$message); $LOCALPORT=2500; $MAXLEN=5151; $USER="REMOVED"; $PASSWORD="REMOVED"; $FILENAME="ports.txt"; #Pull in port mappings. Format is <Patch Panel> , <Switch Port name> I +.E. 13,FastEthernet1/0/20 print "Opening Ports and Reading\n"; open PORTS, $FILENAME or die $!; my @ports=<PORTS>; close PORTS; foreach(@ports) { chomp($_); my @t=split(/,/,$_); $PORTHASH{$t[0]}=$t[1]; } print "Port reading complete\n"; #Open a file to print things to (implemented later on), reusing the sa +me variable. $FILENAME=">data.txt"; #open STDOUT, '>>data.txt' or die $!; #Open Listener on TCP 2500 #$sock= IO::Socket::INET->new(LocalPort => $LOCALPORT,Proto => 'udp') +or die "Socket: $@"; $sock= IO::Socket::INET->new(LocalPort => $LOCALPORT,Proto => 'tcp', R +euse => 1, Listen => SOMAXCONN) or die "Socket: $@"; print "Starting... running on port: $LOCALPORT\n"; while(1) { $client=""; $client = $sock->accept(); $client->recv($message,1024); print "Here AGAIN!6\n"; while (1) { print "In here:\n"; print $message."\n"; #If the packet has the right format of <Switch IP> : <Patch pa +nel mapping>, SSH to it and implement the macro stored on the switch + if ($message=~ /(.*)\:(\d*)/) { #Make sure the port mapping exists, If it does, connect SS +H session my $host=$1; my $portnumber=$2; if (exists $PORTHASH{$portnumber}) { print "Exists!\n"; doSSH($host,$PORTHASH{$portnumber}); print "Here AGAIN!5\n"; last; }else { print"Port: ".$portnumber." is not defined. Host: ".$h +ost.".\n"; $client->send('Not Defined!!'); last; print "Here AGAIN!3\n"; } } else { last; close $client; } last; } } #Clean up sub doSSH { my $host=$_[0]; my $interface=$_[1]; my $s = Net::Appliance::Session->new($host); eval { $s->do_paging(0); $s->do_privileged_mode(0); #Send all SSH output to STDOUT so i can watch it $s->input_log(*STDOUT); print "Connecting to $host\n"; $s->connect(Name => $USER, Password =>$PASSWORD); $s->begin_configure(); $s->cmd("interface ".$interface." "); $s->cmd("macro apply 8021x"); $s->end_configure(); $s->close; }; if ( UNIVERSAL::isa($@,'Net::Appliance::Session::Exception') ) { print $@->message, "\n"; # fault description from Net::Applia +nce::Session print $@->errmsg, "\n"; # message from Net::Telnet print $@->lastline, "\n"; # last line of output from your appl +iance # perform any other cleanup as necessary $client->send('FAILED--'); }else { $client->send('Successful'); } print "Here AGAIN!4\n"; }

Simplesend.pl - just loops forever sending test traffic every 10 seconds.

use IO::Socket; use strict; my $LOCALPORT=2000; my ($newmsg,$MAXLEN,$TIMEOUT); $MAXLEN=5151; $TIMEOUT=5; while (1) { my $counter=10; while ($counter>0) { print "Sending in: ".$counter."\n"; $counter--; sleep 1; } print "Sending!\n\n"; my $sock= IO::Socket::INET->new(Proto => 'tcp', PeerPort=>'2500', +PeerAddr=>'192.168.110.253') or warn "Socket: $@\n"; if ($sock) { print $sock "192.168.250.13:13"; close ($sock); } }

One more piece of info, if anyone wants to run the script to test with actual data, the "ports.txt" file is formatted like this: <number>,<portanme> One per line. I.E. 13,FastEthernet0/2


In reply to TCP Server Exits Loop and Crashes with error by rojmab

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.