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

I have a group of SNMP enabled devices on a remote network, separated from me by a NAT firewall that I need SNMP access to. I am on the outside of the firewall so I have no route to the devices, unless I NATed them out, which I won't do for security reasons. I do have a management server on the inside that is locked down and NATed to the outside that I can SSH into and run my snmp queries. What I am attempting to do is automate this process with a client-server type script. I need to pass the server an IP and a command (what to get) and wait for the server to respond. I have that basic piece of code written as follows: server
#!/usr/bin/perl -w use strict; use IO::Socket; my $socket = IO::Socket::INET->new('LocalPort' => 7890, 'Proto' => 'tcp', 'Listen' => SOMAXCONN) or die "Can't create socket ($!)\n"; print "[Server Started]\n"; while (my $client = $socket->accept) { if ($client->peeraddr) { print "[Connect from " . gethostbyadd +r($client->peeraddr, AF_INET) . "]\n"; } my $reply = "test"; my $act = <$client>; print $act; print $client "$reply\n"; close $client or die "Can't close ($!)\n"; } die "Can't accept socket ($!)\n";
client
#!/usr/bin/perl -w use strict; use IO::Socket; my $host = shift || die "No host"; my $port = 7890; my $action = shift || die "No action"; my $ip = shift || die "No ip"; my $sock = new IO::Socket::INET( PeerAddr => $host, PeerPort => $port, Proto => 'tcp') or die "Can't Bind :$@!\n\n"; print $sock "$action "; print $sock "$ip\n"; while( <$sock> ) { print $_; } close $sock;
I haven't written the meat of the code to perform the SNMP actions, but they will just be subs in a module used in the server program. This works okay for passing pings and pongs back and forth, but I am looking to pass more data. Is there a way I can pass an array or a hash across the socket without formatting it to ASCII first then having to reassemble on the other end? If not, I might just use the SSH module instead and save having to code a server.

Replies are listed 'Best First'.
Re: IO::Socket... passing more then just text
by Fletch (Bishop) on Jun 19, 2008 at 12:10 UTC

    You could marshal the data using Storable, YAML::Syck, JSON::Syck, or Data::Dumper.

    And an alternate suggestion: another approach might be to use HTTP::Daemon (or I believe there's a POE analogue) rather than writing your own protocol and clients completely from the ground up.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: IO::Socket... passing more then just text
by pc88mxer (Vicar) on Jun 19, 2008 at 12:12 UTC
    Is there a way I can pass an array or a hash across the socket without formatting it to ASCII first then having to reassemble on the other end?
    Not that I'm aware of. Passing any sort of data over a socket requires a serialization process.

    If you are looking for modules which will do a lot of the work for you, have a look at Storable - it will serialize just about anything.

    Update: Also have a look at IPC::Socket::SIPC.

Re: IO::Socket... passing more then just text
by zentara (Cardinal) on Jun 19, 2008 at 13:24 UTC
    Is there a way I can pass an array or a hash across the socket without formatting it to ASCII first then having to reassemble on the other end?

    Net::EasyTCP will do it for you transparently. You can essentailly do

    $client->send(\%hash);
    and %hash will be available at the server, (and vice-versa)

    I'm not really a human, but I play one on earth CandyGram for Mongo