[comp.lang.c] sockets/waiting

norman@uxh.cso.uiuc.edu (05/24/89)

Is there a way to check how much data you have waiting
in a socket - so you know if a full message (fixed length
known in advance) has arrived. Esp. if you do not want to 
bother reading it unless you have a full message and would
rather do some processing in the meantime, on a cray for
instance.

Is it possible to receive partial length messages
even if the full messages are (say) only a few
dozen bytes long and are sent out together to you.
Should you be concerned about slow internet transmission
rates fouling up your design if message lengths were to
increase greatly. And messages start getting sent piecemeal.
Should one assume that there will be a natural length that
messages will generally arrive with at the sockets.

I realize my view of the socket interface is probably flawed. 
Any suggestions?

-Salman
e-mail: burkie@rigel.astro.uiuc.edu

chris@mimsy.UUCP (Chris Torek) (05/25/89)

Sockets are not a C-specific topic, but rather a Unix (4BSD) topic.
The question should have been posted to comp.unix.questions; I have
redirected followups there.

In article <12300001@uxh.cso.uiuc.edu> norman@uxh.cso.uiuc.edu writes:
>Is there a way to check how much data you have waiting
>in a socket - so you know if a full message (fixed length
>known in advance) has arrived.

No.  Select (for reading) will tell you whether a read will not block,
but nothing else.  (Actually, the FIONREAD ioctl works on sockets, but
read on.)

>Esp. if you do not want to bother reading it unless you have a full
>message and would rather do some processing in the meantime, on a
>cray for instance.

If a full message is long, and you are using a `stream' socket, you
might never *get* a full message unless you read the first part.
(`Long' varies from one implementation to another, and typically
might be between a few tens of bytes on a machine with too little
memory to a few megabytes on another.)

>Is it possible to receive partial length messages
>even if the full messages are (say) only a few
>dozen bytes long and are sent out together to you.

If you are dealing with a stream socket, yes.

If you are dealing with a datagram socket, messages will always
be delivered in one piece.

I quote from the `Advanced IPC Tutorial', /usr/doc/ps1/08.ipc/2.t:

	Sockets are typed according to the communication properties
	visible to a user.  Processes are presumed to communicate only
	between sockets of the same type, although there is nothing
	that prevents communication between sockets of different types
	should the underlying communication protocols support this.

	Four types of sockets currently are available to a user.  A
	*stream* socket provides for the bidirectional, reliable,
	sequenced, and unduplicated flow of data without record
	boundaries.  Aside from the bidirectionality of data flow, a
	pair of connected stream sockets provides an interface nearly
	identical to that of pipes [footnote:  In the UNIX domain, in
	fact, the semantics are identical and, as one might expect,
	pipes have been implemented internally as simply a pair of
	connected stream sockets.].

	A *datagram* socket supports bidirectional flow of data which
	is not promised to be sequenced, reliable, or unduplicated.
	That is, a process receiving messages on a datagram socket may
	find messages duplicated, and, possibly, in an order different
	from the order in which it was sent.  An important
	characteristic of a datagram socket is that record boundaries
	in data are preserved.  Datagram sockets closely model the
	facilities found in many contemporary packet switched networks
	such as the Ethernet.

	A *raw* socket provides users access to the underlying
	communication protocols which support socket abstractions.
	These sockets are normally datagram oriented, though their
	exact characteristics are dependent on the interface provided
	by the protocol.  Raw sockets are not intended for the general
	user; they have been provided mainly for those interested in
	developing new communication protocols, or for gaining access
	to some of the more esoteric facilities of an existing
	protocol.  The use of raw sockets is considered in section 5.

	A *sequenced packet* socket is similar to a stream socket, with
	the exception that record boundaries are preserved.  This
	interface is provided only as part of the NS socket
	abstraction, and is very important in most serious NS
	applications.  Sequenced-packet sockets allow the user to
	manipulate the SPP or IDP headers on a packet or a group of
	packets either by writing a prototype header along with
	whatever data is to be sent, or by specifying a default header
	to be used with all outgoing data, and allows the user to
	receive the headers on incoming packets.  The use of these
	options is considered in section 5.

	Another potential socket type which has interesting properties
	is the *reliably delivered message* socket.  The reliably
	delivered message socket has similar properties to a datagram
	socket, but with reliable delivery.  There is currently no
	support for this type of socket, but a reliably delivered
	message protocol similar to Xerox's Packet Exchange Protocol
	(PEX) may be simulated at the user level.  More information on
	this topic can be found in section 5.

4BSD TCP/IP supports only stream and datagram sockets (and raw sockets,
which, as mentioned, are not intended for ordinary use).  Craig Partridge
at BBN produced an experimental reliable datagram protocol for IP, but
most machines do not implement it.

>Should you be concerned about slow internet transmission
>rates fouling up your design if message lengths were to
>increase greatly. And messages start getting sent piecemeal.

You may always have to worry about transmission rates, but there is
little you can do to affect them---it is rather like being caught in
a traffic jam on a superhighway sometimes.

>Should one assume that there will be a natural length that
>messages will generally arrive with at the sockets.

There may be such a length, but it may change dynamically.  (TCP/IP
has internally an option to choose an appropriate `segment size',
but it is applied only at connection startup.  Many people feel this
is insufficient.)

>I realize my view of the socket interface is probably flawed. 
>Any suggestions?

Read the ipc tutorials, /usr/doc/ps1/07.ipctut and /usr/doc/ps1/08.ipc.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris