Java Reference
In-Depth Information
starting with “200 OK”), followed by the requested file. Since the client does not know the size
of the file, the server must indicate the end-of-file by closing the socket.
Calling close() on a Socket terminates both directions (input and output) of data flow.
(Subsection 5.4.2 provides a more detailed description of TCP connection termination.) Once an
endpoint (client or server) closes the socket, it can no longer send or receive data. This means
that close() can only be used to signal the other end when the caller is completely finished
communicating. In the echo protocol, once the server receives the close from the client, it
immediately closes. In effect, the client close indicates that the communication is completed.
HTTP works the same way, except that the server is the terminator.
Let's consider a different protocol. Suppose you want a compression server that takes a
stream of bytes, compresses them, and sends the compressed stream back to the client. Which
endpoint should close the connection? Since the stream of bytes from the client is arbitrarily
long, the client needs to close the connection so that the server knows when the stream of
bytes to be compressed ends. When should the client call close() ? If the client calls close() on
the socket immediately after it sends the last byte of data, it will not be able to receive the last
bytes of compressed data. Perhaps the client could wait until it receives all of the compressed
data before it closes, as the echo protocol does. Unfortunately, neither the server nor the client
knows how many bytes to expect, so this will not work either. What is needed is a way to tell
the other end of the connection “I am through sending,” without losing the ability to receive.
Fortunately, sockets provide a way to do this. The shutdownInput() and shutdownOutput()
methods of Socket allow the I/O streams to be closed independently. After shutdownInput() ,
the socket's input stream can no longer be used. Any undelivered data is silently discarded,
and any attempt to read from the socket's input stream will return
1. After shutdownOutput()
is called on a Socket , no more data may be sent on the socket's output stream. Attempts to
write to the stream throw an IOException . Any data written before the call to shutdownOutput()
may be read by the remote socket. After this, a read on the input stream of the remote socket
will return
1. An application calling shutdownOutput() can continue to read from the socket
and, similarly, data can be written after calling shutdownInput() .
In the compression protocol (see Figure 4.2), the client writes the bytes to be compressed,
closing the output stream using shutdownOutput() when finished sending, and reads the
compressed byte stream from the server. The server repeatedly reads the uncompressed data
<Uncompressed bytes>
<Compressed bytes>
<Uncompressed bytes>
Shutdown
<Compressed bytes>
Closed
Figure 4.2: Compression protocol termination.
 
Search WWH ::




Custom Search