perl

时间:2018-03-02 09:12:20

标签: perl sockets

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

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

client.pl stuff:

# !/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 stuff:

# !/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内容&#34; Storable&#34;:

 # !/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内容&#34; Storable&#34;:

 # !/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();

但前面提到的并不适合我。

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

1 个答案:

答案 0 :(得分:3)

调用accept是个问题。摆脱内部const personRoutes: Routes = [ { path: 'view/:id', component: PersonDetailsComponent outlet: 'person' } ]; 循环,只需从套接字读取。在client.pl中,您使用&lt;&gt;执行此操作(a.k.a. readline)运算符,在new_client.pl中,[The fiddle][1] 将隐式为您执行此操作。

while

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