Как я могу поделиться структурами данных Perl через сокет? - PullRequest
4 голосов
/ 13 мая 2010

В сокетах я написал клиент-серверную программу. Сначала я попытался отправить нормальную строку, среди них она отправляет нормально. После этого я попытался отправить значения хеша и массива с клиента на сервер и с сервера на клиент. Когда я печатаю значения с помощью Dumper, он дает мне только эталонное значение. Что я должен сделать, чтобы получить действительные значения на клиентском сервере?

Серверная программа:

use IO::Socket;
use strict;
use warnings;

my %hash = ( "name" => "pavunkumar " , "age" => 20 ) ;
my $new  = \%hash ;
#Turn on System variable for Buffering output
$| = 1;
# Creating a a new socket
my $socket=
IO::Socket::INET->new(LocalPort=>5000,Proto=>'tcp',Localhost =>
        'localhost','Listen' => 5 , 'Reuse' => 1 );
die "could not create $! \n" unless ( $socket );
        print "\nUDPServer Waiting port 5000\n";
        my $new_sock =  $socket->accept();
        my $host =  $new_sock->peerhost();
        while(<$new_sock>)
        {
        #my $line = <$new_sock>;
        print Dumper "$host $_";
        print $new_sock $new . "\n";
        }
        print "$host is closed \n" ;

Клиентская программа

use IO::Socket;                               
use Data::Dumper ;                            
use warnings ;                                
use strict ;                                  

my %hash  = ( "file" =>"log.txt" , size => "1000kb") ;

my $ref = \%hash ;


# This client for connecting the specified below address and port 
# INET function will create the socket file and establish the connection with
# server

my $port = shift || 5000 ;
my $host = shift || 'localhost';
my $recv_data ;
my $send_data;
my $socket = new IO::Socket::INET (
                                  PeerAddr  => $host ,
                                  PeerPort  => $port ,
                                  Proto => 'tcp', )

or die "Couldn't connect to Server\n";
while (1)
{
        my $line = <stdin> ;
        print $socket $ref."\n";
        if ( $line = <$socket> )
        {
                print Dumper  $line ;
        }
        else
        {
                print "Server is closed \n";
                last ;
        }

}

Я дал примерную программу о том, что я делаю. Кто-нибудь может сказать мне, что я делаю неправильно в этом коде? И что мне нужно сделать для доступа к хеш-значениям?

Ответы [ 2 ]

8 голосов
/ 13 мая 2010

Когда вы говорите

print $ref;

, вы частично инструктируете Perl превратить $ref в строку (так как print ed может быть только строка). Оказывается, по умолчанию ссылки не превращаются в очень полезные строки.

Вам нужно превратить $ref в строку, которую вы можете отправить по проводам, а затем декодировать на другой стороне, чтобы получить данные обратно. Этот процесс называется «сериализация». Вывод Data::Dumper на самом деле является действительной сериализацией его аргументов, но базовый модуль сериализации в Perl: Storable.

Процедурно вы можете сказать [1]

use Storable qw(nfreeze); # nfreeze rather than freeze because
                          # we want a network-portable string
...
print nfreeze($ref);

с одной стороны и

use Storable qw(thaw);
...
my $ref = thaw($line);

с другой.

Есть также интерфейс OO; Прочитайте документацию Storable для получения дополнительной информации.

[1]: обратите внимание на yaddayaddas. Это неполный код, который просто иллюстрирует ключевые отличия от вашего кода.

5 голосов
/ 13 мая 2010

Проблема в том, что вы отправляете ссылки на данные, а не на сами данные. Вам нужно как-то сериализовать данные. JSON - это очень простой способ сделать это. Существует также YAML .

...