Although TCP/IP is reliable, much additional
protocol is required to make programs reliable that
use the socket API.

1) When a program on one end of the socket fails, the
program at the other end should be able to restore itself
to a state where it can accept a connection when the partner
program returns. By default, the partner of a failed connection
crashes.

2) It should be possible to operate the message handling
input in such a way that the program is never blocked by
waiting on the socket data. By default, the ioctl that
returns the available byte count only shows the number
of bytes in the first available mbuf. A program that
waits for a fixed message size using this ioctl can
hang forever.

3) If the socket doesn't fail but we have an error in 
the message itself, we want to clear out the data on
the connection, report the error, and continue normal
operations. (This is not a "normal" condition for the
finished application, but it makes the developer's life
a lot easier.)


For item 2, it is sufficient to use timeouts appropriately.
If a socket times out, the Link simply shuts down the connection.
A Downlink will throw a local error. An Uplink will simply
close.

For item 3, we need to insure that the socket is flushed.

Using timeouts:
When a local error is thrown that is not related to the
socket itself, the Uplink catches the error and does
a 5 second flush-read on the socket. It then sends back
the error reply.

Using a total size:
An alternative is to put the total message size in the
message header. This is used only for error recovery.
When an error is caught, the hander reads and discards
the rest of the message. This eliminates then need to
do a flush.

The problem with flushing is that we have to wait for
a timeout. If there are many Uplinks, we may cause other
timeouts.

FOr item 1, we have to use an ioctl to let the program
handle connection failures. When we get a broken connection,
it is handled the same way as a timeout.

CHANGES:

1) mswSocket.c & Alltalk Socket class: Add a timeout parameter
to the sockRead function. Zero does a blocking read.

2) Downlink: (.c and .alt) Pass the total message size.

3) Uplink: (.c and .alt) Use the total message size to flush the
socket after an error.

4) Coops & Alltalk : Enable broken connection exception handling.


