home *** CD-ROM | disk | FTP | other *** search
- <!-- $RCSfile$$Revision$$Date$ -->
- <!-- $Log$ -->
- <HTML>
- <TITLE> PERLIPC </TITLE>
- <h2>NAME</h2>
- perlipc - Perl interprocess communication
- <p><h2>DESCRIPTION</h2>
- The IPC facilities of Perl are built on the Berkeley socket mechanism.
- If you don't have sockets, you can ignore this section. The calls have
- the same names as the corresponding system calls, but the arguments
- tend to differ, for two reasons. First, Perl file handles work
- differently than C file descriptors. Second, Perl already knows the
- length of its strings, so you don't need to pass that information.
- <p><h3>Client/Server Communication</h3>
- Here's a sample TCP client.
- <p><pre>
- ($them,$port) = @ARGV;
- $port = 2345 unless $port;
- $them = 'localhost' unless $them;
- </pre>
- <pre>
- $SIG{'INT'} = 'dokill';
- sub dokill { kill 9,$child if $child; }
- </pre>
- <pre>
- use Socket;
- </pre>
- <pre>
- $sockaddr = 'S n a4 x8';
- chop($hostname = `hostname`);
- </pre>
- <pre>
- ($name, $aliases, $proto) = getprotobyname('tcp');
- ($name, $aliases, $port) = getservbyname($port, 'tcp')
- unless $port =~ /^\d+$/;
- ($name, $aliases, $type, $len, $thisaddr) =
- gethostbyname($hostname);
- ($name, $aliases, $type, $len, $thataddr) = gethostbyname($them);
- </pre>
- <pre>
- $this = pack($sockaddr, &AF_INET, 0, $thisaddr);
- $that = pack($sockaddr, &AF_INET, $port, $thataddr);
- </pre>
- <pre>
- socket(S, &PF_INET, &SOCK_STREAM, $proto) || die "socket: $!";
- bind(S, $this) || die "bind: $!";
- connect(S, $that) || die "connect: $!";
- </pre>
- <pre>
- select(S); $| = 1; select(stdout);
- </pre>
- <pre>
- if ($child = fork) {
- while (<>) {
- print S;
- }
- sleep 3;
- do dokill();
- }
- else {
- while (<S>) {
- print;
- }
- }
- </pre>
- And here's a server:
- <p><pre>
- ($port) = @ARGV;
- $port = 2345 unless $port;
- </pre>
- <pre>
- use Socket;
- </pre>
- <pre>
- $sockaddr = 'S n a4 x8';
- </pre>
- <pre>
- ($name, $aliases, $proto) = getprotobyname('tcp');
- ($name, $aliases, $port) = getservbyname($port, 'tcp')
- unless $port =~ /^\d+$/;
- </pre>
- <pre>
- $this = pack($sockaddr, &AF_INET, $port, "\0\0\0\0");
- </pre>
- <pre>
- select(NS); $| = 1; select(stdout);
- </pre>
- <pre>
- socket(S, &PF_INET, &SOCK_STREAM, $proto) || die "socket: $!";
- bind(S, $this) || die "bind: $!";
- listen(S, 5) || die "connect: $!";
- </pre>
- <pre>
- select(S); $| = 1; select(stdout);
- </pre>
- <pre>
- for (;;) {
- print "Listening again\n";
- ($addr = accept(NS,S)) || die $!;
- print "accept ok\n";
- </pre>
- <pre>
- ($af,$port,$inetaddr) = unpack($sockaddr,$addr);
- @inetaddr = unpack('C4',$inetaddr);
- print "$af $port @inetaddr\n";
- </pre>
- <pre>
- while (<NS>) {
- print;
- print NS;
- }
- }
- </pre>
- <h3>SysV IPC</h3>
- Here's a small example showing shared memory usage:
- <p><pre>
- $IPC_PRIVATE = 0;
- $IPC_RMID = 0;
- $size = 2000;
- $key = shmget($IPC_PRIVATE, $size , 0777 );
- die if !defined($key);
- </pre>
- <pre>
- $message = "Message #1";
- shmwrite($key, $message, 0, 60 ) || die "$!";
- shmread($key,$buff,0,60) || die "$!";
- </pre>
- <pre>
- print $buff,"\n";
- </pre>
- <pre>
- print "deleting $key\n";
- shmctl($key ,$IPC_RMID, 0) || die "$!";
- </pre>
- Here's an example of a semaphore:
- <p><pre>
- $IPC_KEY = 1234;
- $IPC_RMID = 0;
- $IPC_CREATE = 0001000;
- $key = semget($IPC_KEY, $nsems , 0666 | $IPC_CREATE );
- die if !defined($key);
- print "$key\n";
- </pre>
- Put this code in a separate file to be run in more that one process
- Call the file <I>take</I>:
- <p><pre>
- # create a semaphore
- </pre>
- <pre>
- $IPC_KEY = 1234;
- $key = semget($IPC_KEY, 0 , 0 );
- die if !defined($key);
- </pre>
- <pre>
- $semnum = 0;
- $semflag = 0;
- </pre>
- <pre>
- # 'take' semaphore
- # wait for semaphore to be zero
- $semop = 0;
- $opstring1 = pack("sss", $semnum, $semop, $semflag);
- </pre>
- <pre>
- # Increment the semaphore count
- $semop = 1;
- $opstring2 = pack("sss", $semnum, $semop, $semflag);
- $opstring = $opstring1 . $opstring2;
- </pre>
- <pre>
- semop($key,$opstring) || die "$!";
- </pre>
- Put this code in a separate file to be run in more that one process
- Call this file <I>give</I>:
- <p><pre>
- #'give' the semaphore
- # run this in the original process and you will see
- # that the second process continues
- </pre>
- <pre>
- $IPC_KEY = 1234;
- $key = semget($IPC_KEY, 0, 0);
- die if !defined($key);
- </pre>
- <pre>
- $semnum = 0;
- $semflag = 0;
- </pre>
- <pre>
- # Decrement the semaphore count
- $semop = -1;
- $opstring = pack("sss", $semnum, $semop, $semflag);
- </pre>
- <pre>
- semop($key,$opstring) || die "$!";
- </pre>
-