gpt4 book ai didi

perl - perl中数组的序列化用法

转载 作者:行者123 更新时间:2023-12-03 11:51:41 24 4
gpt4 key购买 nike

我有 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 : $!\n";

print "TCP Connection Success.\n";

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 : $! \n";


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

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\n ";

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 内容:
 # !/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 : $! \n";


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

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\n ";

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 内容:
 # !/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 : $!\n";

print "TCP Connection Success.\n";

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();

但上述对我不起作用。

有人可以告诉我我的客户端如何以正确的方式使用序列化来反射(reflect)来自服务器端的多个输出。

最佳答案

调用 accept 是问题所在。摆脱内在while循环并简单地从套接字读取。在 client.pl 中,您在 new_client.pl, fd_retrieve 中使用 <> (又名 readline )运算符执行此操作会为你隐含地做到这一点。

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 - perl中数组的序列化用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49065956/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com