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