[comp.dcom.lans] Streams vs. Sockets

kc@rna.UUCP (02/19/87)

About a year ago someone posted an article comparing streams and sockets
from the perspective of implementing networking protocols. I have recently
become interested in this area, and would welcome any comments on the subject.
A repost of that article would also be nice...

I've written programs that use sockets to access server processes on remote
machines. I've never used a machine that had streams, but I've read the usual
literature. 

Here are some of my observations on sockets/streams:

	Streams has added fewer new system calls than sockets.

	Streams corresponds more closely to the ISO protocol layers.

	Streams are more easily reconfigured to meet the needs of processes.

	Streams cleans up Unix character handling outside of the networkng
realm.

	Sockets have been time tested. (Research 8 users might say
the same about streams.)

	The socket system calls seem to obviously map into the network
protocol arena. Things like accept, listen, and sendto match my notion
of how one would program network communications. I just don't know if it
is similarly easy to create applications using streams.

	The driver-like nature of stream protocol modules makes it easy
to imagine writing my own streams protocol module. (Of course I
might change my mind if I looked at the code.) I have looked at the
Berkeley code for sockets, and I haven't the foggiest notion how I
would implement a new protocol on top of the sockets mechanism.

Kaare Christian
cmcl2!rna!kc

guy@gorodish.UUCP (02/20/87)

>	Streams has added fewer new system calls than sockets.

Yes, but it added tons of new "ioctl" calls and protocol messages,
instead.  Robert Elz, a while ago, refuted the claim that the number
of system calls used by any facility can, in and of itself, be
considered a reasonable figure of merit.

>	Streams corresponds more closely to the ISO protocol layers.

Actually, streams *per se* don't correspond to any protocol layers.
You can implement the layers as streams multiplexor drivers (neither
e.g. TCP nor IP would function very well as streams modules; TCP has
fan-out at the top, and IP has both fan-out at the top and fan-in at
the bottom), but then you can also implement them as different bits
of a 4BSD-style protocol implementation.  They both can match the ISO
protocol layers about equally well.

>	Streams cleans up Unix character handling outside of the networkng
>	realm.

Well, *some* UNIX character handling; dealing with "ioctl"s in a
streams module can be messy.

>	The socket system calls seem to obviously map into the network
>protocol arena. Things like accept, listen, and sendto match my notion
>of how one would program network communications. I just don't know if it
>is similarly easy to create applications using streams.

This brings up one point missed by some "sockets vs. streams"
discussions.  The terms "sockets" and "streams" are used loosely at
times.  Strictly speaking, *neither* sockets *nor* streams are
sufficient to implement networking protocols, in general.  Streams
plus the Transport Layer Interface stream module (plus the "tirdwr"
module, if you want to do something really bizarre and un-UNIX-like
such as doing "read" and "write" rather than "getmsg" and "putmsg" on
descriptors referring to network connections) provides roughly the
same functions as the "socket code" plus the protocol-to-protocol and
protocol-to-network interface code in the 4BSD networking code.

>	The driver-like nature of stream protocol modules makes it easy
>to imagine writing my own streams protocol module.

Be careful here.  I'm not sure the term "driver-like" has any
meaning; the only things that character special file drivers have in
common are that they all have some subset of "open", "close", "read",
"write", and "ioctl" entry points (they may have others, like
"select", "mmap", "reset", etc.).

Even this is only true in a *very* loose sense of streams modules,
which have "open" and "close" routines that are called rather
differently from the way regular character special file drivers'
"open" and "close" routines are called.  They *never* have "read",
"write", nor "ioctl" routines; instead, they may have routines to
receive messages from the modules above or below them, and may have
service procedures to process those messages and send them further
along the stream.  A lot of stuff you'd do in a streams module may be
similar to what you'd do in a conventional driver, but a lot of it is
*very* different.

>I have looked at the Berkeley code for sockets, and I haven't the foggiest
>notion how I would implement a new protocol on top of the sockets mechanism.

Note that you don't generally implement a new protocol on top of
streams; you have to write it to handle the TLI.  There is also a
Link Layer Interface that would roughly correspond to the
protocol-to-network-interface conventions of the 4BSD networking
code, although it's somewhat oriented towards the IEEE 802.2
specification and may or may not be appropriate to other sorts of
networks.  (It also is *not* appropriate for connecting IP to the
link layers it supports, because it requires you to provide the
link-layer address to which a packet is to be sent; IP would prefer a
different interface, which an ARP module would provide, and that ARP
module would talk LLI to the modules below it.)

As such, you'd probably find dealing to those guys about as
complicated as dealing with the 4BSD interfaces.

adam@its63b.UUCP (02/23/87)

	Some care is needed here when making this comparison.
"Sockets" are really a user level interface to networking code.
Streams are an implementation method for networking code.
Therefore they are not strictly comparable.  If you doubt this, reflect
that one could implement the socket interface with stream-based modules.

"Sockets" is also taken to mean the well-known implementation of this
interface that we all know and love.  You can compare this to streams.

		Adam Hamilton

dougm@violet.UUCP (02/27/87)

In article <13748@sun.uucp> guy@sun.UUCP (Guy Harris) writes:

To build on what Guy has stated:

>Actually, streams *per se* don't correspond to any protocol layers.
>You can implement the layers as streams multiplexor drivers (neither
>e.g. TCP nor IP would function very well as streams modules; TCP has
>fan-out at the top, and IP has both fan-out at the top and fan-in at
>the bottom), but then you can also implement them as different bits
>of a 4BSD-style protocol implementation.  They both can match the ISO
>protocol layers about equally well.

To state this a little differently, both streams and sockets (actually
the proto switch code under sockets) provide a "framework" onto which
protocol implementations can be built.  Streams are somewhat more
generalized than sockets, allowing different drivers, modules, etc. to
be linked and stacked in different ways.

As was mentioned, TLI corresponds more closely to what sockets are.
TLI offers some additional flexibility in terms of programmer
interface than sockets, but at the loss of complete generality.  The
TLI streams descriptor cannot be used as an ordinary file descriptor
unless the TLI module is popped and the read/write module pushed on.
You then lose the ability to use TLI operations.

>
>Be careful here.  I'm not sure the term "driver-like" has any
>meaning; the only things that character special file drivers have in
...
>Even this is only true in a *very* loose sense of streams modules,
>which have "open" and "close" routines that are called rather
...
>similar to what you'd do in a conventional driver, but a lot of it is
>*very* different.
>

Streams drivers definitely have some different characteristics from
traditional style drivers.  Some examples that might illustrate how
different are:

    getmsg: there is no read hook into a streams driver.  If you
	    happen to use "read", it turns into a getmsg.  Where
	    getmsg is different is in the fact that it "passively"
	    waits for a message to appear at the stream head.  It
	    doesn't ever give the driver an indication that the user
	    is waiting.
    sleep:  in general, you NEVER sleep on an event in a streams
	    driver or module.  Modules run out of the streams
	    scheduler and a sleep might put the wrong process to sleep
	    (such as the process scheduler or other critical process).

To state it another way, "arrival events" trigger actions and the
components of a "stream" are all scheduled independently.
Doug McCallum		Interactive Systems Corp.
dougm@ico.isc.com	{cbosgd, hao, nbires}!ico!dougm