Search code examples
socketstcp

What happens to the data in a TCP socket's send buffer after the client calls close()?


If the client calls the write() function to write a large amount of data to the buffer of socketfd, and then calls close(socketfd), will the client still send the data remaining in the buffer to the server?


Solution

  • will the client still send the data remaining in the buffer to the server?

    It depends.

    By default, yes. However, you can disable the behavior using the SO_LINGER socket option:

    https://man7.org/linux/man-pages/man7/socket.7.html

    SO_LINGER
    Sets or gets the SO_LINGER option. The argument is a linger structure.

    struct linger {
        int l_onoff;    /* linger active */
        int l_linger;   /* how many seconds to linger for */
    };
    

    When enabled, a close(2) or shutdown(2) will not return until all queued messages for the socket have been successfully sent or the linger timeout has been reached. Otherwise, the call returns immediately and the closing is done in the background. When the socket is closed as part of exit(2), it always lingers in the background.

    This is discussed in more detail on MSDN for Windows (closesocket() is Windows' equivalent to close() for sockets, but the behavior is similar for Posix systems):

    Graceful Shutdown, Linger Options, and Socket Closure

    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 implicitly causes 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 to 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 are still not 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.