Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

"Single-machine IPC via sockets" and other things to say in the dark

by Hot Pastrami (Monk)
on Sep 14, 2000 at 01:00 UTC ( #32360=perlquestion: print w/replies, xml ) Need Help??
Hot Pastrami has asked for the wisdom of the Perl Monks concerning the following question:


I'm trying to find information on using sockets to communicate between 2 Perl scripts running on the same machine, but I've had little luck to date... that info which I can find is all relating to IP sockets over the Internet. The Camel book has some, but written in a way that could make a sockets novice openly weep (for instance: "NAME should be a packed network address of the proper type for the socket"). I've heard rumors that the Perl Cookbook has good examples of it, but my local Barnes and Noble didn't have that one in stock, so I thought I'd see if anyone here could offer help.

Can anyone possibly trouble themselves to post snippets of what the two scripts might look like to pass info between one another via sockets? Although they're on the same machine, one will play a server role, the other a client... the server will wait for and respond to requests from the client. I can figure out the error checking and ugly details, I just need to catch a glimpse of the basic concept in code.

Thanks a whole bunch,

Alan "Hot Pastrami" Bellows
-Sitting calmly with scissors-
  • Comment on "Single-machine IPC via sockets" and other things to say in the dark

Replies are listed 'Best First'.
Re: Single-machine IPC via sockets and other things to say in the dark
by BastardOperator (Monk) on Sep 14, 2000 at 01:25 UTC
    This uses Unix domain sockets, it's from the perlipc manpage. you didn't specify what you were looking for
    #!/usr/bin/perl -w # The client use Socket; use strict; my ($socky, $line); $socky = shift || '/tmp/mysock'; socket(SOCK, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!"; connect(SOCK, sockaddr_un($socky)) || die "connect: $!"; while (defined($line = <SOCK>)) { print $line; } exit; ################# #!/usr/bin/perl -wT # The server use Socket; use strict; use Carp; BEGIN { $ENV{PATH} = '/usr/ucb:/bin'; } sub logit { print "$0 $$: @_ at ", scalar localtime, "\n"; } my $NAME = '/tmp/mysock'; my $uaddr = sockaddr_un($NAME); my $proto = getprotobyname('tcp'); socket(Server,PF_UNIX,SOCK_STREAM,0) || die "socket: $!"; unlink($NAME); bind (Server, $uaddr) || die "bind: $!"; listen(Server,SOMAXCONN) || die "listen: $!"; logit "server started on $NAME"; my $waitedpid; sub REAPER { $waitedpid = wait; $SIG{CHLD} = \&REAPER; logit "reaped $waitedpid" . ($? ? " with exit $?" : ''); } $SIG{CHLD} = \&REAPER; for ($waitedpid = 0; accept(Client,Server) || $waitedpid; $waitedpid = 0, close Client) { next if $waitedpid; logit "connection on $NAME"; spawn sub { print "Hello there, it's now ", scalar localtime, "\n"; exec '/usr/games/fortune' or die "can't exec fortune: +$!"; }; }
      Ahh, this uses the ugly %SIG-handler code that breaks servers sooner or later. There are better ways to reap kids. I have a few samples in my columns. Best look for examples that use a no-wait waitpid at strategic points in the top-level loop.

      -- Randal L. Schwartz, Perl hacker

by Hot Pastrami (Monk) on Sep 14, 2000 at 01:19 UTC

    You are right, however the reason I want to know how to manipulate the sockets directly is because A) I need to accomplish this interaction for a current project, and B) I want to understand the details so I can be the one writing the modules one day (hehe).

    So, if anybody's got a minute to slap up some socket code, why I'd be just as happy as a... well, happy anyway.

    Alan "Hot Pastrami" Bellows
    -Sitting calmly with scissors-
      Okay, responding point by point:
      A) I need to accomplish this interaction for a current project
      The two modules are available today. I show many examples of their usage in my WT columns, as do many other tutorials.
      B) I want to understand the details so I can be the one writing the modules one day
      Good, then you'll want to study good code that does useful things. The source to these modules is well documented and less buggy than almost anything else you'll see on the net. So use the modules, then trace down inside to see what they're doing.

      Do not attempt to build new technology without understanding existing technology. Reinventing the wheel is fine as long as you don't do it ignorantly.

      -- Randal L. Schwartz, Perl hacker

        That's true, examining the code may wield some useful stuff. By point A I wasn't implying that the modules weren't available, I was just describing how the need to get it done was only half my motivation, next to the need to understand. Turn, turn, turn.

        Alan "Hot Pastrami" Bellows
        -Sitting calmly with scissors-
Re: IPC via sockets
by ncw (Friar) on Sep 14, 2000 at 01:20 UTC
    If you want an easy to use perl only way of doing this then look at Net::Daemon, and the related RPC::pServer and Net::pRPC::Client.

    It comes with a simple example of a calculator server which is a few dozen lines of perl. You might prefer this to merlyn's solution as it is probably lower overhead. Less buzzword friendly though ;-)


Re: intramachine IPC via sockets
by merlyn (Sage) on Sep 14, 2000 at 01:06 UTC
    Again, I can't overemphasize the advantage of using a well-known-protocol for the communication. In this case, my favorite round-trip of choice is HTTP. Look into creating a server with HTTP::Daemon, and then your client can perform transactactions with easily-generated LWP::UserAgent objects.

    -- Randal L. Schwartz, Perl hacker

by Fastolfe (Vicar) on Sep 14, 2000 at 17:42 UTC
    Generally stuff made for the Internet will always work on the local host as well. You can set up "Internet" sockets and do IPC that way, just connecting to 'localhost' to do the deed.

    Generally, however, if you want to limit your process's interaction to processes running on the local machine, you should consider Unix domain sockets, which work a lot like Internet sockets, but you listen on a special file, and have your other process "connect" to this file.

    Both of these options have the added benefit/drawback of being able to serve any type of client that wants to interact with your "server" script, including clients that don't have any business doing this. If this is a problem, you may want to look into shared memory pools or pipes.

    The perlipc man page has some great example code.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://32360]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2017-03-22 22:25 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (276 votes). Check out past polls.