NAME
IO::Socket::SIPC - Serialized perl structures for inter process communication.
SYNOPSIS
use IO::Socket::SIPC;
DESCRIPTION
This module makes it possible to transport perl structures between processes over sockets. It wrappes your favorite IO::Socket module and controls the amount of data over the socket. The default serializer is Storable and the functions nfreeze() and thaw() but you can choose each serialize you want. You need only some lines of code to adjust it for yourself. Take a look to the method documentation and it's options.
METHODS
new()
Call new()
to create a new IO::Socket::SIPC object.
read_max_bytes Set the maximum allowed bytes to read from the socket.
send_max_bytes Set the maximum allowed bytes to send over the socket.
favorite Set your favorite module, IO::Socket::INET or IO::Socket::SSL.
deflate Pass your own sub reference for serializion.
inflate Pass your own sub reference for deserializion.
Defaults
read_max_bytes unlimited
send_max_bytes unlimited
favorite IO::Socket::SSL
deflate nfreeze of Storable
inflate thaw of Storable (in a Safe compartment)
You can set your favorite socket handler. Example:
use IO::Socket::SIPC;
my $sipc = IO::Socket::SIPC->new( favorite => 'IO::Socket::INET' );
The only mandatory thing is that your favorite must provide an accept()
method to wait for connections because accept()
of IP::Socket::SIPC used it.
Also you can set your own serializer if you like. Example:
use IO::Socket::SIPC;
use Convert::Bencode_XS;
my $sipc = IO::Socket::SIPC->new(
deflate => sub { Convert::Bencode_XS::bencode($_[0]) },
inflate => sub { Convert::Bencode_XS::bdecode($_[0]) },
);
# or
use IO::Socket::SIPC;
use JSON::PC;
my $sipc = IO::Socket::SIPC->new(
deflate => sub { JSON::PC::convert($_[0]) },
inflate => sub { JSON::PC::parse($_[0]) },
);
NOTE that the code that you handoff with deflate and inflate is embed in an eval block and if it produce an error you can get the error string by calling errstr()
. If you use the default deserializer of Storable the data is deserialized in a Safe compartment. If you use another deserializer you have to build your own Safe compartment within your code ref!
read_max_bytes(), send_max_bytes()
Call both methods to increase or decrease the maximum bytes that the server or client is allowed to read()
or send()
. Possible sizes are KB, MB and GB or just a number for bytes. It's not case sensitiv and you can use KB
or kb
or just k
. If you want set the readable size to unlimited then you can call both methods with 0 or unlimited
. The default max send and read size is unlimited.
Here some notations examples
$sipc->read_max_bytes(1048576);
$sipc->read_max_bytes('1024k');
$sipc->read_max_bytes('1MB');
# unlimited
$sipc->read_max_bytes('unlimited');
$sipc->read_max_bytes(0);
connect()
Call connect()
to connect to the socket. connect()
just call new()
of your favorite socket creator and handoff all params to it. Example:
my $sipc = IO::Socket::SIPC->new( favorite => 'IO::Socket::INET' );
$sipc->connect(
PeerAddr => 'localhost',
PeerPort => '50010',
Proto => 'tcp',
);
# would call intern
IO::Socket::INET->new(@_);
accept()
If a Listen socket is defined then you can wait for connections with accept()
. accept()
is just a wrapper to the original accept()
method of your favorite socket handler.
If a connection is accepted a new object is created related to the peer. The new object will be returned.
disconnect()
Call disconnect()
to disconnect the current connection. disconnect()
calls close()
on the socket that is referenced by the object.
sock()
Call sock()
to access the object of your favorite module.
IO::Socket::INET examples:
$sipc->sock->timeout(10);
# or
$sipc->sock->peerhost;
# or
$sipc->sock->peerport;
# or
my $sock = $sipc->sock;
$sock->peerhost;
Note that if you use
while (my $c = $sipc->sock->accept) { }
that $c is the unwrapped IO::Socket::INET object and not a IO::Socket::SIPC object.
send()
Call send()
to send data over the socket to the peer. The data will be serialized and packed before it sends to the peer. The data that is handoff to send()
must be a reference. If you handoff a string to send()
then it's a reference is created on the string.
send()
returns the length of the serialized data or undef on errors or if send_max_bytes is overtaken.
read()
Call read()
to read data from the socket. The data will be unpacked and deserialized before it is returned. Note that if you send a string that the string is returned as a scalar reference.
If the maximum allowed bytes is overtaken or an error occured then read()
returns undef and aborts reading from the socket.
errstr()
Call errstr()
to get the current error message if a method returns undef. errstr()
is not useable with new()
because new fails by wrong settings.
Note that errstr()
do not contain the error message of your favorite module, because it's to confused to find the right place for the error message. As example the error message from IO::Socket::INET is provided in $@
and from IO::Socket::SSL in IO::Socket::SSL-
errstr()>. Maybe the error message of your favorite is placed somewhere else. errstr()
contains only a short message of what happends in IO::Socket::SIPC. If you want to know the right message of your favorite try something like...
# IO::Socket::INET
$sipc->connect(%options) or die $sipc->errstr($@);
# IO::Socket::SSL
$sipc->connect(%options) or die $sipc->errstr($sipc->sock->errstr);
# Your::Favorite
$sipc->connect(%options) or die $sipc->errstr($YourFavoriteERRSTR);
# or just
$sipc->connect(%options) or die $sipc->errstr($!);
EXAMPLES
Take a look to the examples directory.
Server example
use strict;
use warnings;
use IO::Socket::SIPC;
my $sipc = IO::Socket::SIPC->new();
$sipc->connect(
LocalAddr => 'localhost',
LocalPort => 50010,
Proto => 'tcp',
Listen => 10,
Reuse => 1,
SSL_verify_mode => 0x01,
SSL_ca_file => '../certs/ca.pem',
SSL_cert_file => '../certs/servercert.pem',
SSL_key_file => '../certs/serverkey.pem',
SSL_passwd_cb => sub {return "megaraptor"},
) or die $sipc->errstr($sipc->sock->errstr);
warn "server initialized\n";
$sipc->sock->timeout(10);
while ( 1 ) {
while (my $client = $sipc->accept()) {
print "connect from client: ", $client->sock->peerhost, "\n";
my $request = $client->read or die $client->errstr($client->sock->errstr);
next unless $$request;
chomp($$request);
warn "client says: $$request\n";
$client->send({ foo => 'is foo', bar => 'is bar', baz => 'is baz'}) or die $client->errstr($client->sock->errstr);
$client->disconnect or die $client->errstr($!);
}
warn "server runs on a timeout, re-listen on socket\n";
}
$sipc->disconnect or die $sipc->errstr($!);
Client example
use strict;
use warnings;
use Data::Dumper;
use IO::Socket::SIPC;
my $sipc = IO::Socket::SIPC->new();
$sipc->connect(
PeerAddr => 'localhost',
PeerPort => 50010,
Proto => 'tcp',
SSL_use_cert => 1,
SSL_verify_mode => 0x01,
SSL_ca_file => '../certs/ca.pem',
SSL_cert_file => '../certs/clientcert.pem',
SSL_key_file => '../certs/clientkey.pem',
SSL_passwd_cb => sub { return "pyroraptor" }
) or die $sipc->errstr($sipc->sock->errstr);
warn "client connected to server\n";
$sipc->send("Hello server, gimme some data :-)\n") or die $sipc->errstr($sipc->sock->errstr);
my $answer = $sipc->read or die $sipc->errstr($sipc->sock->errstr);
warn "server data: \n";
warn Dumper($answer);
$sipc->disconnect or die $sipc->errstr($!);
PREREQUISITES
UNIVERSAL - to check for routines with can()
UNIVERSAL::require - to post load favorite modules
IO::Socket::SSL - for the test suite and examples
Storable - the default serializer and deserializer
Safe - deserialize (Storable::thaw) in a safe compartment
EXPORTS
No exports.
REPORT BUGS
Please report all bugs to <jschulz.cpan(at)bloonix.de>.
AUTHOR
Jonny Schulz <jschulz.cpan(at)bloonix.de>.
QUESTIONS
Do you have any questions or ideas?
MAIL: <jschulz.cpan(at)bloonix.de>
IRC: irc.perl.org#perlde
COPYRIGHT
Copyright (C) 2007 by Jonny Schulz. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.