NAME
    IO::Socket::SIPC - Serialize perl structures for inter process
    communication.

SYNOPSIS
        use IO::Socket::SIPC;

        my $sipc = IO::Socket::SIPC->new(
           favorite       => 'IO::Socket::INET',
           use_check_sum  => 1,
           read_may_bytes => '512k',
           send_may_bytes => '512k'
        );

        $sipc->connect(
           LocalAddr       => $address,
           LocalPort       => $port,
           Proto           => $proto,
           Listen          => $listen,
           ReuseAddr       => $reuse,
        ) or die $sipc->errstr;

        my $client = $sipc->accept($timeout);

        my %perl_struct = (
           hash  => { foo => 'bar' },
           array => [ 'foo', 'bar' ],
        );

        $client->send( \%perl_struct );

DESCRIPTION
    This module makes it possible to transport perl structures between
    processes. It wrappes your favorite IO::Socket module and controls the
    amount of data and verifies it with a checksum.

    The default serializer is Storable with "nfreeze()" and "thaw()" and the
    default checksum generator is Digest::MD5 with "md5()" but you can
    choose any other serializer or checksum generator you wish to use, there
    are just some restrictions that you have to comply with and you only
    need to adjust a few lines of code by yourself.

METHODS
  new(\%config)
    The "new()" constructor method creates a new IO::Socket::SIPC object. A
    list of parameters as a hash or a hash reference may be passed to it.

        favorite        Set your favorite module - IO::Socket::(INET|UNIX|SSL).
        deflate         Pass your own sub reference for serializion.
        inflate         Pass your own sub reference for deserializion.
        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.
        use_check_sum   Check each transport with a MD5 sum.
        gen_check_sum   Set up your own checksum generator.

    The defaults are:

        favorite        IO::Socket::INET
        deflate         nfreeze() of Storable
        inflate         thaw() of Storable (in a Safe compartment)
        read_max_bytes  unlimited
        send_max_bytes  unlimited
        use_check_sum   disabled (enable it with 1)
        gen_check_sum   md5() of Digest::MD5 if use_check_sum is enabled

    favorite
        Set your favorite socket handler - IO::Socket::INET,
        IO::Socket::UNIX or IO::Socket::SSL.

            use IO::Socket::SIPC;

            my $sipc = IO::Socket::SIPC->new( favorite => 'IO::Socket::SSL' );
    
    deflate, inflate
        Set your own serializer:

            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 to deflate and inflate is
        embedded in an eval block for executions and if 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!

    use_check_sum
        Turn it on (1) or off (0) for the current object.

        If you turn it on then a checksum is generated for any packet that
        is transportet.

        The default checksum generator is "md5()" of Digest::MD5.

    gen_check_sum
        Use your own checksum generator:

            use Digest::SHA2;

            my $sha2obj = new Digest::SHA2;

            my $sipc = IO::Socket::SIPC->new(
                gen_check_sum => sub { $sha2obj->digest($_[0]) }
            );

        But I think Digest::MD5 is very well and it does it's job.

    read_max_bytes, send_max_bytes
        Increase or decrease the maximum size of bytes that a peer is
        allowed to send or read. 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". Notations:

            # 1 MB
            read_max_bytes => 1048576
            read_max_bytes => '1024k'
            read_max_bytes => '1MB'

            # unlimited
            read_max_bytes => 0
            read_max_bytes => unlimited

        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 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(@_);

    You can pass all params that are allowed of your favorite. I don't check
    it.

  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. If a connection is accepted then a new object
    is created related to the peer. The new object will be returned on
    success, undef on error and 0 on a timeout.

    You can set a timeout value in seconds.

        my $c = $sipc->accept(10)
        warn "accept: timeout" if defined $c;

  is_timeout()
    Another check if you want to know if "accept()" return FALSE because a
    timeout happends.

        while ( 1 ) {
           while ( my $c = $sipc->accept(10) ) {
              # processing
           }
           warn "accept: timeout" if $sipc->is_timeout;
        }

  disconnect()
    Call "disconnect()" to disconnect the current connection. "disconnect()"
    calls "close()" on the socket that is referenced by the object.

        my $c = $sipc->accept();
        $c->disconnect;    # to close $c
        $sipc->disconnect; # to close $sipc

  sock()
    Call "sock()" to access the raw object of your favorite module.

    IO::Socket::INET examples:

        $sipc->sock->timeout(10);
        # or
        $peerhost = $sipc->sock->peerhost;
        # or
        $peerport = $sipc->sock->peerport;
        # or
        $sock = $sipc->sock;
        $peerhost = $sock->peerhost;

    NOTE that if you use

        while ( my $c = $sipc->sock->accept ) { ... }

    that $c is the unwrapped IO::Socket::* 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
    occurs 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's returned. If the maximum 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()". Note
    that "read_raw()" and "send_raw()" doesn't work with references!

  errstr()
    Call "errstr()" to get the current error message if a method returns
    FALSE. "errstr()" is not useable with "new()" because "new()" croaks
    with incorrect arguments.

    NOTE that "errstr()" returns the current error message and contain $! if
    necessary. If you use IO::Socket::SSL then the message from
    IO::Socket::SSL->errstr is appended as well.

  debug()
    You can turn on a little debugger if you like

        $sipc->debug(1);

    It you use IO::Socket::SSL then $IO::Socket::SSL::DEBUG is set to level
    that you passed with "debug()".

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',
           use_check_sum => 1,
        );

        $sipc->connect(
           LocalAddr  => 'localhost',
           LocalPort  => 50010,
           Proto      => 'tcp',
           Listen     => 10, 
           Reuse      => 1,
        ) or die $sipc->errstr;

        $sipc->debug(1);

        while ( 1 ) { 
           my $client;
           while ( $client = $sipc->accept(10) ) { 
              print "connect from client: ", $client->sock->peerhost, "\n";
              my $request = $client->read_raw 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;
           }   
           die $sipc->errstr unless defined $client;
           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',
           use_check_sum => 1,
        );

        $sipc->connect(
           PeerAddr => 'localhost',
           PeerPort => 50010,
           Proto    => 'tcp',
        ) or die $sipc->errstr;

        $sipc->debug(1);

        $sipc->send_raw("Hello server, gimme some data :-)\n") 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::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 <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

TODO AND IDEAS
        * do you have any ideas?
        * maybe another implementations of check sum generators
        * do you like to have another wrapper as accept()? 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.

