|
Graceful shutdown, linger options and socket closure
The following material is provided as clarification for the subject of
shutting down socket connections closing the sockets. It is important to distinguish
the difference between shutting down a socket connection and closing a socket.
Shutting down a socket connection involves an exchange of protocol messages
between the two endpoints, hereafter referred to as a shutdown sequence. Two
general classes of shutdown sequences are defined: graceful and abortive (also called
"hard"). In a graceful shutdown sequence, any data that has been queued but
not yet transmitted can be sent prior to the connection being closed. In an
abortive shutdown, any unsent data is lost. The occurrence of a shutdown sequence
(graceful or abortive) can also be used to provide an FD_CLOSE indication to the
associated applications signifying that a shutdown is in progress.
Closing a socket, on the other hand, causes the socket handle to become
deallocated so that the application can no longer reference or use the socket in any
manner.
In Windows Sockets, both the shutdown function, and the WSASendDisconnect function can be used to initiate a shutdown sequence, while the closesocket function is used to deallocate socket handles and free up any associated
resources. Some amount of confusion arises, however, from the fact that the closesocket function will implicitly cause a shutdown sequence to occur if it has not
already happened. In fact, it has become a rather common programming practice to
rely on this feature and use closesocket to both initiate the shutdown sequence and deallocate the socket handle.
To facilitate this usage, the sockets interface provides for controls by way
of the socket option mechanism that allow the programmer to indicate whether the
implicit shutdown sequence should be graceful or abortive, and also whether
the closesocket function should linger (that is not complete immediately) to allow time for a
graceful shutdown sequence to complete. These important distinctions and the
ramifications of using closesocket in this manner have not been widely understood.
By establishing appropriate values for the socket options SO_LINGER and
SO_DONTLINGER, the following types of behavior can be obtained with the closesocket function:
- Abortive shutdown sequence, immediate return from closesocket.
- Graceful shutdown, delaying return until either shutdown sequence completes or
a specified time interval elapses. If the time interval expires before the
graceful shutdown sequence completes, an abortive shutdown sequence occurs, and closesocket returns.
- Graceful shutdown, immediate return
allowing the shutdown sequence to complete in the background. Although this
is the default behavior, the application has no way of knowing when (or whether)
the graceful shutdown sequence actually completes.
One technique that can be used to minimize the chance of problems occurring
during connection teardown is to avoid relying on an implicit shutdown being
initiated by closesocket. Instead, use one of the two explicit shutdown functions, shutdown or WSASendDisconnect ). This in turn will cause an FD_CLOSE indication to be received by the peer
application indicating that all pending data has been received. To illustrate
this, the following table shows the functions that would be invoked by the
client and server components of an application, where the client is responsible for
initiating a graceful shutdown.
Client Side
| Server Side
| (1) Invoke shutdown(s, SD_SEND) to signal end of session and that client has no more data to send.
|
|
| (2) Receive FD_CLOSE, indicating graceful shutdown in progress and that all
data has been received.
|
| (3) Send any remaining response data.
| (5') Get FD_READ and invoke recv to get any response data sent by server
| (4) Invoke shutdown(s, SD_SEND) to indicate server has no more data to send.
| (5) Receive FD_CLOSE indication
| (4') Invoke closesocket
| (6) Invoke closesocket
|
|
Note The timing sequence is maintained from step (1) to step (6) between the
client and the server, except for step (4') and (5') which only has local timing
significance in the sense that step (5) follows step (5') on the client side
while step (4') follows step (4) on the server side, with no timing relationship
with the remote party.
Related Links
Software for Delphi and C++ Builder developers
Software for Visual Studio .NET developers
Software for Visual Basic 6 developers
Delphi Tips&Tricks
MegaDetailed.NET
More Online Helps
Win32 Programmer's Reference (win32.hlp)
Win32 Multimedia Programmer's Reference (mmedia.hlp)
OLE Programmer's Reference (ole.hlp)
Microsoft Windows Pen API Programmer's Reference (penapi.hlp)
Microsoft Windows Telephony API (TAPI) Programmer's Reference (tapi.hlp)
Unix Manual Pages
|