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

I need a perl client-server implementation as a wrapper for a server in C#. A perl script passes the server address and port number and an input string to a module, this module has to create the socket and send the input string to the server.

The data sent has to follow ISO-8859-1 encoding. On receiving the information, the client has to first receive 3 byte, then the next 8 bytes, this has the length of the data that has to be received next.. so based on the length the client has to read the next data.

Each of the data that is read has to be stored in a variable and sent another module for further processing.

Currently this is what my perl client looks like..which I'm sure isn't right..could someone tell me how to do this..and set me on the right direction..

sub WriteInfo { my ($addr, $port, $Input) = @_; $socket = IO::Socket::INET->new ( Proto => "tcp", PeerAddr => $addr, PeerPort => $port, ); unless ($socket) { die "cannot connect to remote" } while (1) { $socket->send($Input); } } sub ReadData { while (1) { my $ExecutionResult = $socket->recv( $recv_data, 3); my $ +DataLength = $socket->recv( $recv_data, 8); $DataLength =~ s/^0+// ; + my $decval = hex($DataLength); my $Data = $socket->recv( $recv_data, + $decval); return($Data); }
thanks a lot.. Perllace

Replies are listed 'Best First'.
Re: Object Oriented Perl interface to read from and write to a socket
by zentara (Cardinal) on Mar 11, 2011 at 15:13 UTC
Re: Object Oriented Perl interface to read from and write to a socket
by locked_user sundialsvc4 (Abbot) on Mar 11, 2011 at 14:47 UTC

    If you are asking for guidance here, my first suggestion to you would be this:   that your true purpose here is, not “to create a Perl object that talks to a socket,” but rather “to create a Perl object that will serve as a black-box interface to a remote system.”

    Of course, a search of CPAN (http://search.cpan.org) instantly points us to modules such as IO::Socket – this merely being among the first of 1,291 hits for the word, “socket.”   (Footnote:   A search for “ISO-8859-1” yields 248 more!)   Your Perl object can, and undoubtedly will, use such a package in its implementation.   But the purpose of this class (or, as the case may be, classes) will be, not only to handle the low-level mechanics of the basic protocol, but to intelligently and conveniently handle the messages, as well.

    Ideally, no client of your module would have to care about where the server is (except for its IP-address and maybe port), nor exactly how it talks to you, nor exactly what it says.   The module becomes the perfect interpreter ambassador... excellent at what it does, so that nobody else has to.

    (And if, at the conclusion of your due-diligence search of CPAN, it so happens that you have just invented a new CPAN module, please consider contributing it.)

Re: Object Oriented Perl interface to read from and write to a socket
by Eliya (Vicar) on Mar 11, 2011 at 14:59 UTC

    Here's an 'OO-style' example (including a server part, so it can be run standalone):

    #!/usr/bin/perl -w use strict; use IO::Socket; my $pid = fork(); unless ($pid) { # --- server my $server = IO::Socket::INET->new( #LocalAddr => 'localhost', LocalPort => 12345, Proto => "tcp", Listen => SOMAXCONN, Reuse => 1, ) or die "couldn't create listening socket: $!"; print "server listening...\n"; while (1) { my $client = $server->accept(); print "client connected\n"; while (<$client>) { if (/^foo/) { $client->print("bar"); # 3 bytes (dummy) $client->print("0000001f"); # 8 bytes length as hex s +tring $client->print("X" x 0x1f); # data last; } } $client->close(); print "connection closed\n"; } exit; } else { # --- client sleep 1; my $conn = MyConnection->new('localhost', 12345); $conn->WriteInfo("foo\n"); my $data = $conn->ReadData(); print "data: '$data'\n"; } END { kill 15, $pid; print "server shut down\n"; } package MyConnection; use base "IO::Socket::INET"; sub new { my $class = shift; my ($addr, $port) = @_; my $socket = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $addr, PeerPort => $port, ) or die "couldn't connect: $!"; $socket->autoflush(); return bless $socket, $class; } sub WriteInfo { my $sock = shift; my $info = shift; print "client sending request\n"; $sock->print($info); } sub ReadData { my $sock = shift; $sock->read(my $dummy, 3); $sock->read(my $len_hex, 8); my $len = hex($len_hex); print "client reading response ($len bytes)\n"; $sock->read(my $data, $len); return $data; }
    $ ./892650.pl server listening... client connected client sending request client reading response (31 bytes) data: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' connection closed server shut down
      Thank you Eliya..i think this will work.