Named-Pipes and Sockets

Sockets?

Here is a "popular" non-exact description. (help me out with a better one: mail).

The sockets concept is one way of performing interprocess communication (IPC). It enables programs on the same computer to seek each other out and talk to each other. But it doesn't stop there, sockets work also for programs running on a network (anywhere on the internet if you're so wired).

To use sockets for IPC you need to write and run server and client programs. The server runs on your local computer and is under your control. The client processes can be anywhere on the network (your own computer(s) as a special case) and are not necessarily of your own making. A server listens on a port for clients wanting to make contact. For remote clients to contact your server they need to know your computer name and the port number the server is using. Popular examples with servers available on almost all computers are FTP (port 20), TELNET (port 23), FINGER (port 79), TIME-OF-DAY (port 13) and QUOTE (port 17). Your own server just picks a port number that happens to be not in use (for instance 3145). Most sockets-based IPC works by sending strings back and forth between server and client using some kind of published protocol. For your own use you just think something up that works. Because you're using Forth, the protocol is the easy part--sending counted strings and using EVALUATE will work nicely.

In its easiest form, starting a server on your computer looks like this:

         3145 myserver

Here 3145 is the port number your server listens to (more or less arbitrarily picked). "Myserver" is a Forth colon definition containing (probably) an endless loop. It checks if a client tries to make contact on port 3145 and then exchanges strings with this client according to some protocol of your own design (no rules I know off). Socket communication is bidirectional.

The client part is just as simple. Assuming the client runs also on your own computer you would start it like this:

      S" //." 3145 myclient

or

      S" frunobulax" 3145 myclient

assuming your computer is named "frunobulax". Any URL is okay as long as you also provide a valid port number and your server is active there. Note that you can use the iForth word hostname ( -- c-addr u ) to return your computer name.

If you have progressed this far you will learn more by downloading the socket related files above. The files extend iForth with the following socket wordset:

OPEN-SERVICE ( c-addr u port# -- socket ) example: S" frunobulax" 3145 OPEN-SERVICE ( -- 4 )
CREATE-SERVER ( port# -- lsocket ) example: 3145 CREATE-SERVER ( -- 16 )
LISTEN ( lsocket /queue -- )  example: 16 7 LISTEN
ACCEPT-SOCKET ( lsocket -- socket ) example: 16 ACCEPT-SOCKET ( -- 3 )
READ-SOCKET ( socket c-addr maxlen -- c-addr size ) example: 3 PAD 125 READ-SOCKET ( -- 'pad 125 )
WRITE-SOCKET ( c-addr size socket -- ) example: PAD 128 3 WRITE-SOCKET
CLOSE-SOCKET ( socket -- ) example: 3 CLOSE-SOCKET
+CR ( c-addr1 u1 -- c-addr2 u2 ) appends a hard CR+LF pair to the text
BLOCKING-MODE ( socket on/off -- ) put the socket in/out of blocking mode
SET-SOCKET-TIMEOUT ( u -- ) set the global timeout (in ms) on reading sockets
GET-SOCKET-TIMEOUT ( -- u ) get the global timeout (in ms) on reading sockets

Named Pipes?

Again a "popular" non-exact description. (a better one: mail).

A named pipe is a second way of performing interprocess communication (IPC). Programs on the same computer (Linux), or anywhere on the network or internet (only Windows NT 4.0 file systems allowed), can seek each other out and talk to each other. The difference with using sockets is that you don't need the rather arbitrary port number, just a specially formatted (equally arbitrary :-) file name. Also, I don't know of any publicly accessible named pipes on the internet. Like sockets, one writes Forth programs for the server and client ends, and IPC works by sending strings back and forth between server and client using a (published) protocol of your own design.

In its easiest form, starting a named pipe server on your computer looks like this:

              S" //./pipe/forthserver" serverspeed ( Windows )
    
              S" /dev/forthserver" serverspeed  ( Linux )
   

Here the file name defines the path the clients take to your server (arbitrarily picked). Note the "/pipe" part of the path, this is required for Windows NT. "Serverspeed" is a Forth colon definition (probably) containing an endless loop. It checks if a client tries to make contact and then exchanges strings with this client according to some protocol of your own design. Named pipe communication is bidirectional.

The client part is just as simple. Assuming the client runs also on your own computer you would start it like this:

      S" //./pipe/forthserver" clientspeed

or

      S" //frunobulax/pipe/forthserver" clientspeed

or

      S" /dev/forthserver" clientspeed

assuming your computer is named "frunobulax" (Linux doesn't support named pipes over the network).

If you have progressed this far you can learn more by downloading the named pipe related files above. The files extend iForth with the following named pipe wordset:

OPEN-NAMED-PIPE ( c-addr u timeout -- handle ) example: S" //frunobulax/pipe/clientspeed" 5000 OPEN-NAMED-PIPE ( -- 3 )
CREATE&ACCEPT ( c-addr u -- handle ) example: S" //frunobulax/pipe/serverspeed" CREATE&ACCEPT ( -- 3 )
READ-NAMED-PIPEX ( c-addr maxlen handle -- c-addr size ) example: PAD 125 3 READ-NAMED-PIPEX ( -- 'pad 125 )
WRITE-NAMED-PIPE ( c-addr size handle -- ) example: PAD 128 3 WRITE-NAMED-PIPE
CLOSE-NAMED-PIPE ( handle -- ) example: 3 CLOSE-NAMED-PIPE
You may find that this wordset is a somewhat easier to understand than the socket wordset, although sockets are more versatile (can use any URL).

Windows

Both socket and named pipe wordsets work for iForth (resp. any Windows and Windows NT 4.0). Normally, for a UNIX system, the handles and sockets are compatible with the file system READ-FILE WRITE-FILE and CLOSE-FILE words. Because of Microsoftisms this doesn't work for Windows. Therefore iForth has given the read/write/close actions new names, although it wouldn't be strictly necessary for iForth Linux. The named pipe set doesn't support multiple clients connecting to a single server (it looks like Windows NT 4.0 supports it, but I can't figure out how).

Note that current Windows documentation states that named pipe servers need better than Windows 2000 Server, and named pipe clients need better than Windows 2000 Professional. I couldn't get the cliserv2.frt example to work on my current Windows XP Pro installations.

Linux

The socket and named pipe wordsets also work for Linux. The named pipes are not so useful because they won't function over a network. However, you can connect multiple clients to a single server, which the Windows implementation should allow, but doesn't (meaning I can't find how to do it). Named pipes are done using sockets and modified code from W. Richard Stevens' "Advanced Programming in the UNIX Environment".

Performance

There is a noticeable difference in performance between sockets and named pipes.

Benchmark 1: 20 Mbytes copied between two iForths on machine 1;
Benchmark 2: 20 Mbytes copied from an iForth on machine 2 to an iForth on machine 1.

Systems for sock test: Windows XP Pro, running on (1) an Intel PIV 3GHz/1GB and (2) an Intel Core 2 Duo 2.66 GHz/2GB. The PC's were networked using motherboard Realtek network adapters (100 Mbit/s).
Systems for npipe test: Windows NT 4.0, running on (1) an Intel Pentium 166MHz/48MB and (2) an Intel Pentium 200MHz/48MB. The PC's were networked using cheap NE2000 clones (10 Mbit/s).

benchmark  | process A read | process B write
===========+================+================
sock  bm 1 |    72 MB/sec   |   732 MB/sec
sock  bm 2 |  11.5 MB/sec   | 2.857 GB/sec
npipe bm 1 |    15 MB/sec   |    15 MB/sec
npipe bm 2 |   715 KB/sec   |   715 KB/sec
(The benchmarks were also done under Linux and performed even better there.)

As you can see, sockets look nice for processes on different machines, while named pipes are good for processes on the same machine. For Linux there should be almost no difference between sockets and named pipes.

I suggest using sockets for everything: portable, fast, and work across networks and operating systems.

A translation of this page into Bulgarian, by Albert Ward.


Valid HTML 3.0