3

我正在尝试在 Perl 中创建一个套接字客户端。服务器端是在本地主机上运行的 C 程序。

我必须通过套接字发送哈希。这是我正在使用的一段代码。

sub applyGlobalConfig {
    my ($globalConfig, $ignoreData) = @_;

    my $socket = IO::Socket::INET->new(PeerAddr => $PEER_HOST,
                                       PeerPort => $PEER_PORT,
                                       Proto    => "tcp",
                                       Type     => SOCK_STREAM)
          or die "Couldn't connect to $PEER_HOST:$PEER_PORT : $@\n";

    my $reconfigResult;

    print $socket "$113\n";

    close($socket);

    unless ($reconfigResult) {
        return 0;
    }

    return ERR_NULL;
}

现在,我的问题是,$globalConfig将包含一个哈希引用,我想通过套接字发送它。我无法弄清楚。我用谷歌搜索并找到了一些对 Dumper 的参考,但不太了解。如何发送哈希?

4

2 回答 2

6

要通过套接字发送数据结构,您必须将其“序列化”为字节流。然后接收程序必须对其进行反序列化以重新组装数据结构。如果接收程序期望流采用特定格式,则发送程序必须生成期望的格式。

如果您正在编写双方,那么您可以选择一种对您的情况有意义的序列化格式,例如 JSON 或 XML,其中任何一种都可以表示 Perl 哈希。但是,在不了解您的具体情况的更多详细信息的情况下,这就是可以以答案的方式提供的所有信息。

于 2012-12-04T07:21:56.380 回答
1

我更喜欢为此使用Storable模块。例子:

接收端:

use strict;
use IO::Socket::INET;
use Storable;
use Data::Dumper;

my   $sock = IO::Socket::INET->new(Listen    => 5, LocalAddr => 'host',
                                 LocalPort => 9000,  Proto     => 'tcp');
while( my $s = $sock->accept ) {
    my $struct = Storable::fd_retrieve($s);
    print Dumper($struct);
}

发送方:

use strict;
use IO::Socket::INET;
use Storable;

my   $sock = IO::Socket::INET->new(PeerAddr => 'host',  PeerPort => 9000,
                 Type     => SOCK_STREAM, Proto     => 'tcp') || die "Fail: $!";
my $struct = {
    a => 1,
    b => [2,3,4]
};
Storable::nstore_fd($struct, $sock);

通过从 i386 Linux 发送到 amd64 FreeBSD 进行测试。

您也可以使用 Data::Dumper 从哈希生成字符串,然后通过网络发送,但它的方法很脏而且有问题。

升级版:

但是,我正在努力如何将 perl 端的哈希值转换为用空格分隔的字符串。

尝试使用连接/映射组合:

my $serialized = join("\n", map { "$_ ".$struct->{$_} } keys %$struct)."\n";

可能在 C 端更容易使用以空字符结尾的字符串:

my $keyvalue_count = scalar keys(%$struct);
my $serialized = join("\0", map { "$_\0".$struct->{$_} } keys %$struct)."\0";

在这个简单的情况下,我更喜欢使用最后一个变体,因为它是 C 的原生版本。

于 2012-12-04T07:53:36.980 回答