Transfering hashes (and arrays and compound structures), via Storable's freeze() & thaw() works nicely and reasonably quickly, but there are a few things to be aware of.
- Remember to binmode your sockets if that's not your local default.
- Use a binary length prefix (not a trailing delimiter), to indicate the size of the binary transmission.
- Use read rather than <$sock> for reading binary messages.
- If your protocol requires the mixing of text and binary messages, pay careful attention to delimiters.
A silly self-contained client-server sample:
#! perl -slw
use strict;
use threads;
use IO::Socket;
use Storable qw[ freeze thaw ];
use Data::Dump qw[ pp ];
my %hash;
@hash{ 'a'..'z' } = 1 .. 26;
my $lsn = new IO::Socket::INET(
Listen => 1, LocalPort => '12345'
) or die "Failed to open listening port: $!\n";
async{
while( my $c = $lsn->accept ) {
binmode $c;
print "Connect from $c";
while( my $cmd = <$c> ) {
print "Got '$cmd'";
last if $cmd =~ m[^quit];
printf $c "%s", pack "N/a*", freeze \%hash;
}
print "Got quit from $c";
close $c;
}
}->detach;
sleep 2;
my $s = new IO::Socket::INET(
'localhost:12345'
) or die "Failed to connect to server: $!";
binmode $s;
for ( 1 .. 1+rand 100 ) {
print $s 'givemeit'; print 'Sent givemeit';
my $len;
read( $s, $len, 4 ) or die "Read failed: $!";
$len = unpack 'N', $len; print "read length: $len";
my $hashStr;
read( $s, $hashStr, $len ) or die "Read failed: $!";
print "Read hashstr length: ", length $hashStr;
my %hash = %{ thaw $hashStr };
pp \%hash;
}
print $s 'quit';
close $s;
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
|