perl中数组的序列化用法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了perl中数组的序列化用法相关的知识,希望对你有一定的参考价值。

我有perl客户端和服务器。我使用IO :: Socket在它们之间发送数据。

客户端可以向服务器发送任何命令,服务器运行它并将响应发送回客户端 - 监视行为方法。

client.pl的东西:

# !/usr/bin/perl
use 5.022;
use strict;
use warnings;

#tcpclient.pl

use IO::Socket::INET;

my $addr = shift @ARGV;
my $port = shift @ARGV;

# flush after every write
$| = 1;

my ($socket,$client_socket);

# creating object interface of IO::Socket::INET modules which 
internally creates 
# socket, binds and connects to the TCP server running on the specific 
port.
$socket = new IO::Socket::INET  (
PeerHost => $addr,
PeerPort => $port,
Proto => 'tcp',
) or die "ERROR in Socket Creation : $!
";

print "TCP Connection Success.
";

while (1) {
my $msg = <STDIN>;
$socket->send ($msg);

my $res = <$socket>;
print $res;

}

$socket->close();

server.pl的东西:

# !/usr/bin/perl
use 5.022;
use strict;
use warnings;

#tcpserver.pl

use IO::Socket::INET;

# flush after every write
$| = 1;

my ( $socket,      $client_socket );
my ( $peeraddress, $peerport );

# creating object interface of IO::Socket::INET modules which 
internally does
# socket creation, binding and listening at the specified port 
address.

$socket = new IO::Socket::INET->new(
LocalHost => '0.0.0.0',
LocalPort => '55555',
Proto     => 'tcp',
Listen    => SOMAXCONN,
Reuse     => 1
) or die "ERROR in Socket Creation : $! 
";


print "server waiting for client connection on port 55555
";

while ( $client_socket = $socket->accept() ) {

# waiting for new client connection.

# get the host and port number of newly connected client.
$peeraddress = $client_socket->peerhost();
$peerport    = $client_socket->peerport();

#print "Accepted New Client Connection From : $peeraddress, 
$peerport
 ";

while (<$client_socket>) {

    print "[$peeraddress $peerport] $_";
    my $data = `$_`;
    print $data;

    $client_socket->send($data);

}

}

    $socket->close();

如果命令的输出是一个字符串(命令如uptimeunamepwd),一切都可以。如果输出包含更多字符串,例如ip a我在客户端只得到一个字符串。

我发现为了解决这个问题,我们可以使用序列化方法。通过这种方式,我们可以使用可以从服务器端发送的数组,其中包含所有字符串。

我已经通过StackOverflow进行了解析,发现了很多这样的方法:

How can I send an array in client server program in Perl?

How do I encode a simple array into JSON in Perl?

Perl socket sending hash

这是我尝试更改客户端和服务器端的方式,以防Storable模块使用:

新的server.pl与“Storable”的东西:

 # !/usr/bin/perl
 use 5.022;
 use strict;
 use warnings;

 #tcpserver.pl

 use IO::Socket::INET;
 use Storable qw(nstore_fd);


 # flush after every write
 $| = 1;

 my ( $socket,      $client_socket );
 my ( $peeraddress, $peerport );

 # creating object interface of IO::Socket::INET modules which 
 internally does
 # socket creation, binding and listening at the specified port 
 address.

 $socket = new IO::Socket::INET->new(
 LocalHost => '0.0.0.0',
 LocalPort => '55555',
 Proto     => 'tcp',
 Listen    => SOMAXCONN,
 Reuse     => 1
 ) or die "ERROR in Socket Creation : $! 
";


 print "server waiting for client connection on port 55555
";

 while ( $client_socket = $socket->accept() ) {

 # waiting for new client connection.

 # get the host and port number of newly connected client.
 $peeraddress = $client_socket->peerhost();
 $peerport    = $client_socket->peerport();

#print "Accepted New Client Connection From : $peeraddress, 
$peerport
 ";

while (<$client_socket>) {

    print "[$peeraddress $peerport] $_";

    #serialization approach
    #save command output in array
    my @data = `$_`;
    print @data;

    #store and send the whole array
    nstore_fd( @data, $client_socket );

}

}

$socket->close();

新的client.pl“Storable”的东西:

 # !/usr/bin/perl
 use 5.022;
 use strict;
 use warnings;

 #tcpclient.pl

 use IO::Socket::INET;
 use Data::Dumper;
 use Storable qw(fd_retrieve);

 my $addr = shift @ARGV;
 my $port = shift @ARGV;

 # flush after every write
 $| = 1;

 my ($socket,$client_socket);

 # creating object interface of IO::Socket::INET modules which 
 internally creates 
 # socket, binds and connects to the TCP server running on the 
 specific port.
 $socket = new IO::Socket::INET  (
 PeerHost => $addr,
 PeerPort => $port,
 Proto => 'tcp',
 ) or die "ERROR in Socket Creation : $!
";

 print "TCP Connection Success.
";

while (1) {
my $msg = <STDIN>;
$socket->send ($msg);

   #serialization approach
   #retrieve the array 
   while(my $s = $socket ->accept){
    my $struct = fd_retrieve($s);
    print Dumper($struct);
   }

}

$socket->close();

但前面提到的并不适用于我。

有人可以告诉我,我的客户端如何能够以正确的方式使用序列化来反映服务器端的多个输出。

答案

打电话给accept是个问题。摆脱内部while循环,只需从套接字读取。在client.pl中,您使用<>(a.k.a。readline)运算符执行此操作,在new_client.pl中,fd_retrieve将隐式为您执行此操作。

while (1) {
    my $msg = <STDIN>;
    $socket->send($msg);
    my $struct = fd_retrieve($socket);
    print Dumper($struct);
}

PS:升级到IO::Socket::IP,以便获得IPv6支持。升级到Sereal以获取serialisation,因为Storable与不同的Perl版本不兼容。

以上是关于perl中数组的序列化用法的主要内容,如果未能解决你的问题,请参考以下文章

hash 在 perl 中的用法(转载)

perl中的队列

如何有条件地将 C 代码片段编译到我的 Perl 模块?

perl 多fasta文件匹配,并提取匹配文件第一条序列

js数组高阶方法reduce经典用法代码分享

js数组高阶方法reduce经典用法代码分享