NAME IO::Socket::SIPC - Serialize 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 with nfreeze() and thaw() but you can choose each other serializer you wish to use. You have just follow some restrictions and need only some lines of code to adjust it for yourself. In addition it's possible to use a checksum to check the integrity of the transported data. Take a look to the method section. 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 or something else. deflate Pass your own sub reference for serializion. inflate Pass your own sub reference for deserializion. timeout Set up a timeout one time on accept(). This option is only useful if your favorite socket creator provides a timeout() method. Otherwise is occurs an error. use_check_sum Check each transport with a MD5 sum. gen_check_sum Set up your own checksum generator. Defaults read_max_bytes unlimited send_max_bytes unlimited favorite IO::Socket::INET deflate nfreeze() of Storable inflate thaw() of Storable (in a Safe compartment) timeout not used until you set it gen_check_sum md5() of Digest::MD5 use_check_sum enabled (disable it with 0) You can set your favorite socket handler. Example: use IO::Socket::SIPC; my $sipc = IO::Socket::SIPC->new( favorite => 'IO::Socket::SSL' ); NOTE that the only mandatory thing is that your favorite must provide an "accept()" method to wait for connections because the "accept()" method of IP::Socket::SIPC used it. If your favorite doesn't provide an "accept()" method it or it's another name then please request this feature by send me a email. I will try to wrap it or disable checking the existence of "accept()"! 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 maybe 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 an error occurs you can get the error string by calling "errstr()". If you use the default deserializer of Storable then 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! It's just as well possible to use your own checksum generator if you like (dummy example): my $sipc = IO::Socket::SIPC->new( gen_check_sum => sub { Your::Fav::gen_sum($_[0]) } ); But I think Digest::MD5 is very well and it does it's job. read_max_bytes() and 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 or sendable 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); NOTE that the readable and sendable size is computed by the serialized and deserialized data or on the raw data if you use "read_raw()" or "send_raw()". 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 creator. If a connection is accepted then a new object is created related to the peer. The new object will be returned. In addition you can set a timeout value in seconds if your favorite module provides a "timeout()" method. while ( my $c = $sipc->accept(10) ) { ... } 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. If you use the default serializer then you must handoff a reference, otherwise an error occure because "nfreeze()" of Storable just works with references. $sipc->send("Hello World!"); # this would fail $sipc->send(\"Hello World!"); # this not If you use your own serializer then consult the documentation for what the serializer expect. "send()" returns 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. If the maximum read bytes is overtaken or an error occured then "read()" returns undef and aborts to read from the socket. read_raw() and send_raw() If you want to read or send a raw string and disable the serializer for a single transport then you can call "read_raw()" or "send_raw()". 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( favorite => 'IO::Socket::INET' ); $sipc->connect( LocalAddr => 'localhost', LocalPort => 50010, Proto => 'tcp', Listen => 10, Reuse => 1, ) or die $sipc->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(1) or die $client->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->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( favorite => 'IO::Socket::INET' ); $sipc->connect( PeerAddr => 'localhost', PeerPort => 50010, Proto => 'tcp', ) or die $sipc->errstr($@); warn "client connected to server\n"; $sipc->send("Hello server, gimme some data :-)\n", 1) or die $sipc->errstr($!); my $answer = $sipc->read or die $sipc->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::INET - to create sockets Digest::MD5 - to check the data before and after transports Storable - the default serializer and deserializer Safe - deserialize (Storable::thaw) in a safe compartment EXPORTS No exports. REPORT BUGS Please report all bugs to . AUTHOR Jonny Schulz . QUESTIONS Do you have any questions or ideas? MAIL: IRC: irc.perl.org#perlde TODO AND IDEAS * do you have any ideas? * maybe another implementations of check sum generators * do you need another wrapper as accept() or timeout()? Tell me! * auto authentification 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.