Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Nov 1996 08:48:55 -0600 (CST)
From:      Joe Greco <jgreco@brasil.moneng.mei.com>
To:        stesin@gu.net (Andrew Stesin)
Cc:        hackers@freebsd.org, squid-users@nlanr.net
Subject:   Re: Programming technique for non-forking servers?
Message-ID:  <199611131448.IAA23190@brasil.moneng.mei.com>
In-Reply-To: <Pine.BSI.3.95.961113122121.8648B-100000@creator.gu.kiev.ua> from "Andrew Stesin" at Nov 13, 96 12:32:33 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> Hello people,
> 
> can anyone point me to some book, or URL(s), where the
> programming technique for writing non-forking network server
> daemons is described in details? with caveats, non-obvious
> places...
> 
> I mean those like Squid, Harvest cached, probably Gated
> (there is also a non-forking WWW server somewhere, but
> I forgot it's name, for a pity).  AFAIK they are written
> around a huge select(), and are using asynchronous I/O.
> Yes, there are sources, but I'd really like to read
> some general theory on the subject.
> 
> Thanks in advanse!

I don't know about a book, etc., but many programs work on this paradigm,
including inetd, the X11 Xserver, INN, various MUD and IRC type programs,
etc.

The idea is that you have a set of existing connections, and a socket on
which to accept new connections.

In a while(1) loop, you do a select() on all of the FD's above.

Then you iterate through the select return data, looking for FD's marked
for read.

If the "new connections" FD is marked for read, you accept() a new conn
and add it to your list of existing conn's.

If an "existing connection" FD is marked for read, you read from it, 
possibly buffering the data in some sort of "input buffer", and when
you receive a complete message, you dispatch it to a handler of some
sort.  Presumably the handler is very quick and returns "instantly",
if not, you are holding off the servicing of other connections.

In that case, it gets trickier.  If, for example, you are writing
gobs of data from a file to the client, that may take a while over a 
9600 baud IP link.  You modify your select() loop to have both a read 
and a write FD mask, and your "handler" then becomes a mechanism to 
simply open the file.  Your "write handler" then reads data from the
file and writes it to the socket as space allows.

In the case of a "complex" server, i.e. something like an Xserver or
MUD, but probably not a Web server, you probably need to use state machine 
concepts.  This is not "difficult", the only real problem is mastering 
the concept of state machines.

In all cases, the main principle behind a single server process is that
YOU MUST NOT BLOCK (or take an unusually large amount of time to do
something).

That is the nutshell version of a select() based server process.  If you
have specific questions, I may be able to fill in some details.

... JG



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611131448.IAA23190>