Reputation: 822
I am trying to create a socket client in Perl. The server side is a C program running on the local host.
I have to send a hash over the socket. Here is the piece of code I am using.
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;
}
Now, the question I have is, the $globalConfig
will contain a hash reference, and I want to send this over a socket. I am unable figure out. I googled and found some reference to Dumper but couldn’t understand much. How do I send the hash over?
Upvotes: 3
Views: 1345
Reputation: 7357
I'd prefer to use Storable module for this. Example:
Receive-side:
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);
}
Send-side:
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);
Tested by sending from i386 Linux to amd64 FreeBSD.
Also you can use Data::Dumper to make string from hash and then send over network but its dirty and buggy method.
UPD:
But, I am struggling how to convert the values in the hash on perl side to a string separated by space.
Try to use join/map combination:
my $serialized = join("\n", map { "$_ ".$struct->{$_} } keys %$struct)."\n";
Probably on C side its easier to use null-terminated string:
my $keyvalue_count = scalar keys(%$struct);
my $serialized = join("\0", map { "$_\0".$struct->{$_} } keys %$struct)."\0";
In this simple case i'd prefer to use last variant since its native to C.
Upvotes: 1
Reputation: 86764
To send a data structure over a socket you have to "serialize" it into a byte stream. Then the receiving program has to deserialize it to reassemble the data structure. If the receiving program is expecting the stream to be in a specific form, the sending program must produce the expected format.
If you are writing both sides, then you can choose a serialization format that makes sense for your situation, such as JSON or XML, either of which can represent a Perl hash. However, without knowing much more detail about your specific situation, this is about all that can be provided in the way of an answer.
Upvotes: 6