Java Reference
In-Depth Information
Call close()
Returns immediately
Established
Close-Wait
Close
handshake
initiated
by remote
completes
Local port
P
Local port
P
Finish close handshake,
delete stru cture
Local IP
A.B.C.D
Local IP
A.B.C.D
Remote port
Q
Remote port
Q
Remote IP
W.X.Y.Z
Remote IP
W.X.Y.Z
Figure 5.11: Closing after the other end closes.
Figure 5.11 shows the simpler sequence of events at the endpoint that does not close first.
When the closing handshake message arrives, an acknowledgment is sent immediately, and the
connection state becomes “Close-Wait.” At this point, we are just waiting for the application
to invoke the Socket 's close() method. When it does, the final close handshake is initiated
and the underlying socket structure is deallocated, although references to its original Socket
instance may persist in the Java program.
In view of the fact that both close() and shutdownOutput() return without waiting for
the closing handshake to complete, you may wonder how the sender can be assured that sent
data has actually made it to the receiving program (i.e., to Delivered ). In fact, it is possible
for an application to call close() or shutdownOutput() and have it complete successfully (i.e.,
not throw an Exception) while there is still data in SendQ . If either end of the connection then
crashes before the data makes it to RecvQ , data may be lost without the sending application
knowing about it.
The best solution is to design the application protocol so that the side that calls close()
first does so only after receiving application-level assurance that its data was received. For
example, when our TCPEchoClient program receives the echoed copy of the data it sent, there
should be nothing more in transit in either direction, so it is safe to close the connection.
Java does provide a way to modify the behavior of the Socket 's close() method, namely,
the setSoLinger() method. setSoLinger() controls whether close() waits for the closing hand-
shake to complete before returning. It takes two parameters, a boolean that indicates whether
to wait, and an integer specifying the number of seconds to wait before giving up. That is,
when a timeout is specified via setSoLinger() , close() blocks until the closing handshake is
completed, or until the specified amount of time passes. At the time of this writing, how-
ever, close() provides no indication that the closing handshake failed to complete, even if
the time limit set by setSoLinger() expires before the closing sequence completes. In other
words, setSoLinger() does not provide any additional assurance to the application in current
implementations.
Search WWH ::




Custom Search