[comp.unix.programmer] Berkley sockets

carroll@cs.uiuc.edu (Alan M. Carroll) (03/20/91)

I'm going to move this over to comp.unix.programmer, because it's
changed into a socket programming discussion.

In article <16730@uudell.dell.com>, mjhammel@Kepler.dell.com (Michael J. Hammel) writes:
> In article <1991Mar14.193619.21766@m.cs.uiuc.edu>, carroll@cs.uiuc.edu
> (Alan M. Carroll) writes:
> > [ Can't poll() listening sockets ]
> Hmm.  Maybe I don't understand the problem, but how about doing it like this:
> 
> for (;;)             /* begin infinite loop waiting for new connections */
>    {
>    if ( (t=accept(s, &isa, &i) ) < 0)
>       {
> 	...error checking code
>       }
> 
>    if ( (childpid=fork()) == 0) /* child process if fork() returns 0  */
>       {
> 	...handle connection here in child process; the child inherits the socket
>       }

There's a number of reasons for not doing it that way. The program
that I am writing is a "software bus", which accepts messages from a
set of clients, and routes those messages to the set of clients that
are interested in them. Each client connects to the bus via a scoket,
which is used to send messages to other clients, and receive them.

1. I don't like fork(), and avoid it whenever possible. Partly it's a
resource thing (particularly process slots), and partly because I
consider dealing with child processes painful, buggy, and less than
portable.

2. For connecting on sockets, I think that fork() only makes sense if
the child processes do significantly different things, as for example
in inetd. However, in my program every socket is treated in exactly
the same way. Therefore, that functionality should be moved into the
single program, to save CPU, memory, and process slots.

3. Because of the nature of the program, data from any socket can have
a need to be sent to an arbritrary subset of all the other sockets. In
order to do this using child process, each child process would have to
have a means of communicating with either all the other child
processes (and detect when any of them exited), or with the parent
process which would then forward the messages. The former is too ugly
to even discuss*. The latter can't work, because it brings us back to
the original problem - how does the parent move the data when it's
hanging on an accept?

4. I don't have threads, which might otherwise seem like a better
solution.

*This is of course the problem the program was built to solve.
-- 
Alan M. Carroll                "I hate shopping with the reality-impaired"
Epoch Development Team                 - Susan
CS Grad / U of Ill @ Urbana    ...{ucbvax,pur-ee,convex}!cs.uiuc.edu!carroll

leh@atlantis.cis.ufl.edu (Les Hill) (03/26/91)

In article <1991Mar19.202408.14706@m.cs.uiuc.edu>, carroll@cs.uiuc.edu (Alan M. Carroll) writes:

|> There's a number of reasons for not doing it that way. The program
|> that I am writing is a "software bus", which accepts messages from a
|> set of clients, and routes those messages to the set of clients that
|> are interested in them. Each client connects to the bus via a scoket,
|> which is used to send messages to other clients, and receive them.
 
|> 3. Because of the nature of the program, data from any socket can have
|> a need to be sent to an arbritrary subset of all the other sockets. In
|> order to do this using child process, each child process would have to
|> have a means of communicating with either all the other child
|> processes (and detect when any of them exited), or with the parent
|> process which would then forward the messages. The former is too ugly
|> to even discuss*. The latter can't work, because it brings us back to
|> the original problem - how does the parent move the data when it's
|> hanging on an accept?
|> -- 
|> Alan M. Carroll                "I hate shopping with the reality-impaired"
|> Epoch Development Team                 - Susan
|> CS Grad / U of Ill @ Urbana    ...{ucbvax,pur-ee,convex}!cs.uiuc.edu!carroll

As it happens, I have just been putting the final touches on a library which uses
sockets to allow communications to any one peer or all peers; clearly, the leap to any subset is routine matter.  Ignoring the origins of this library for the moment,
the scheme I used could be modified from its completely distrubuted control system into a client/server system to meet your needs.  To give you the short answer, use select in your server (or software bus) and for every client use a SIGIO handler (obviously after setting the socket connection to the server for async.)  As the SIGIO handler is invoked read in the data from the server and store it, use a netread() (or some such routine) to access the stored data as your client needs it, writes can be made di







rectly to the server.  [Obviously, a protocol of some sort needs to be used between the clients and the server -- I am guessing that you already have most of it ironed out.]  If the idea of SIGIO scares you, you could use select or fork off a child that would handle the network connection (and communicate via a pipe or some such.)

-- 
Extraordinary crimes against the people and the state have to be avenged by
agents extraordinary.  Two such people are John Steed -- top professional, and
his partner, Emma Peel -- talented amateur; otherwise known as "The Avengers."
UUCP: ...!gatech!uflorida!leh    BITNET: vishnu@UFPINE    INTERNET: leh@ufl.edu