How can my program tell when a socket connection is broken when it is using stream classes to read/write to the socket?
The only ways to know a connection is broken abnormally (indeed, the definitions of a broken connection), are:
- you send a packet and fail to get a reply within a "reasonable" time
- you try to read a packet and fail to receive data within a "reasonable" time
(The TCP KEEP_ALIVE feature uses polling in the transport layer to periodically check the connection in this manner.)
The buffer is in the transport layer, which is implemented by the OS and not by any Java or native code. Packets that are received by the transport layer need to be buffered for use by the application layer. JDK 1.1+ gives you some socket options which affect the transport layer, for example setSoLinger(). JDK 1.3 gives more control over the options, including buffering, through the Socket methods setSendBufferSize(), setReceiveBufferSize(), etc.
It stands to reason that no less than an entire packet must be received, even though the application may only be requesting a few bytes. TCP must buffer the unused data. Likewise, on sending, TCP tries to aggregate small packets for efficiency - you have some control over this through setTcpNoDelay().
Of course a Socket could also be shut down deliberately, in which case a negotiated end to the TCP session takes place and you find this out immediately (an IOException might be thrown, for instance).