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ハッシュ参照が含まれているので、これをソケット経由で送信したいということです。私は理解できません。私はググってダンパーへの言及を見つけましたが、あまり理解できませんでした。ハッシュを送信するにはどうすればよいですか?

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 側では、null で終わる文字列を使用する方が簡単です。

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

この単純なケースでは、C にネイティブであるため、最後のバリアントを使用することをお勧めします。

于 2012-12-04T07:53:36.980 に答える