Server- and Client-Processes on one machine

Martin Weitzel martin at mwtech.UUCP
Thu Feb 22 01:35:15 AEST 1990


In article <1278 at nixpbe.UUCP> capitain.pad at nixpbe.uucp (Pit Capitain) writes:
>Hi, we want to set up the following system:

First, I would consider to split the server into two processes.
>
>			input data
>			     |
>			     V
			  packager
			     |
			     |<--------
			     V         \
>			server process  \
>		       /     |      \    |
>		      V      V       V	 |
>		  client  client  client/
>		  proc 1  proc 2  proc 3
>
[description of communication deleted,
refer to original article if required]

In the following text I call the connections between the processes
"communication streams". Through this communications streams flows
'input data' and 'control commands'. I have sketched only one path
for control commands from client 3 to the server, but every client
is allowed to send control commands. You may choose to implement
the communication streams either using named pipes or with SysV
messages. For selection criteria of theese two mechanism see later.

The 'packager' has the task to make the 'input data' distinguishable
from control commands sent to the server on the same communication
stream (between packager and server). If the 'input data' is allready
packaged in some form AND send to the server ith a suitable communication
mechanism, the packager process is obsolete.

The advantage you gain from this extension is, that the server can
easily wait for data, because it has only one incomming communication
stream (packaged input data or control commands). There is still one
potential problem: If the server sends too much data to one client,
which - for some unknown reason - doesn't read the data, the server
may have to wait on write to the communication stream. (NOTE: named
pipes are capable of buffering 5 to 10 KByte). This problem can be
avoided by requiring the clients to send some control command, if
they have read all their data and want to see more. (You may also
look at this as the clients 'prompting' the server for more data.)
The server should never send more data, than can be buffered in
the communication stream to the client, before another control
command arrives, which tells 'all data read'.

As an aside, there is also an easy way to 'time out' the server,
if it has to do something periodically: have a daemon process insert
a special control command into the communication stream TO the
server in the intervalls you want to have your timeouts. (As
the 'timeout daemon' would do nothing but sleep between sending
this controll commands, you could make it even more sophisticated:
Let the timeout daemon read some communication stream FROM the
server and the server tell the desired timeout to the daemon,
before the server reads its incomming communication stream.)

The decission wether to use named pipes or messages for the
communication streams needs not be made at an early point in
design. (In fact, you may use both as an alternative implementation.)
For the sake of portability, I would recommend named pipes. If your
only concern is SysV, using messages will simplify things a little,
because message borders are kept intact during transport,
while with named pipes you must implement some protocoll to
seperate the (logical) messages when read by the server.

Again, if you encapsulate the communication by a logical layer,
the actual transport mechanism would be secondary. (You could
even switch to shared memory, if the amount of data to exchange
is huge. In this case the sequential mechanisms only signals the
availability of data.)

I did post this suggestions rather than email to the poster, because
I have learned that programmers often want to implement such
loosely related client-server schemes. Many of them then run into
the situation, that there is a two (or n-) way communication
necessary with several ends to read from, in one or more processes.
This introduces a general problem on UNIX (non BSD versions without
'sockets' and 'select').

To get around the problem, programmers often tend to step into
one of the following cumbersum direction:
1) They look for some mechanism to tell, "if data is available
   on this or that communication stream";
2) they try to "time out reading" in one or the other way;
3) they start to play dangerous games with asynchroneous
   communication streams (signals). 
All of this only introduces new sorrows: 1) leads to the problem
of busy waiting, 2) tends to produce non optimal response times
and 3) is not only hard to get right but worse, inherantly unreliable
(except on BSD UNIX).

As I have shown above, the clean solution is to have any process
read no more than one incomming communication stream. This can
generally be achieved at the expense of one (or a few) additional
process(es). Furthermore, waiting for data to read can be timed
out in a very clean way.

-- 
Martin Weitzel, email: martin at mwtech.UUCP, voice: 49-(0)6151-6 56 83
-- 
Martin Weitzel, email: martin at mwtech.UUCP, voice: 49-(0)6151-6 56 83



More information about the Comp.unix.questions mailing list