AlexKutsan
AlexKutsan

Reputation: 31

Socket is open after process, that opened it finished

After closing client socket on sever side and exit application, socket still open for some time.

I can see it via netstat

Every 0.1s: netstat -tuplna  | grep 6676    
tcp        0      0 127.0.0.1:6676          127.0.0.1:36065         TIME_WAIT   -

I use log4cxx logging and telnet appender. log4cxx use apr sockets. Socket::close() method looks like that:

void Socket::close() {
    if (socket != 0) {
        apr_status_t status = apr_socket_close(socket);
        if (status != APR_SUCCESS) {
            throw SocketException(status);
        }        
        socket = 0;
    }
}

And it's successfully processed. But after program is finished I can see opened socket via netstat, and if it starts again log4cxx unable to open 6676 port, because it is busy. I tries to modify log4cxx. Shutdown socket before close:

void Socket::close() {
    if (socket != 0) {
        apr_status_t shutdown_status = apr_socket_shutdown(socket, APR_SHUTDOWN_READWRITE);
        printf("Socket::close shutdown_status %d\n", shutdown_status);
        if (shutdown_status != APR_SUCCESS) {
            printf("Socket::close WTF %d\n", shutdown_status != APR_SUCCESS);
            throw SocketException(shutdown_status);
        }
        apr_status_t close_status = apr_socket_close(socket);
        printf("Socket::close close_status %d\n", close_status);
        if (close_status != APR_SUCCESS) {
            printf("Socket::close WTF %d\n", close_status != APR_SUCCESS);
            throw SocketException(close_status);
        }
        socket = 0;
    }
}

But it didn't helped, bug still reproduced.

Upvotes: 3

Views: 2720

Answers (3)

Luis Colorado
Luis Colorado

Reputation: 12708

TIME_WAIT is a socket state to allow all in travel packets that could remain from the connection to arrive or dead before the connection parameters (source address, source port, desintation address, destination port) can be reused again. The kernel simply sets a timer to wait for this time to elapse, before allowing you to reuse that socket again. But you cannot shorten it (even if you can, you had better not to do it), because you have no possibility to know if there are still packets travelling or to accelerate or kill them. The only possibility you have is to wait for a socket bound to that port to timeout and pass from the state TIME_WAIT to the CLOSED state.

If you were allowed to reuse the connection (I think there's an option or something can be done in the linux kernel) and you receive an old connection packet, you can get a connection reset due to the received packet. This can lead to more problems in the new connection. These are solved making you wait for all traffic belonging to the old connection to die or reach destination, before you use that socket again.

Upvotes: 0

Paul Rubel
Paul Rubel

Reputation: 27242

As noted by Calvin this isn't a bug, it's a feature. Time Wait is a socket state that says, this socket isn't in use any more but nevertheless can't be reused quite yet.

Imagine you have a socket open and some client is sending data. The data may be backed up in the network or be in-flight when the server closes its socket.

Now imagine you start the service again or start some new service. The packets on the wire aren't aware that its a new service and the service can't know the packets were destined for a service that's gone. The new service may try to parse the packets and fail because they're in some odd format or the client may get an unrelated error back and keep trying to send, maybe because the sequence numbers don't match and the receiving host will get some odd error. With timed wait the client will get notified that the socket is closed and the server won't potentially get odd data. A win-win. The time it waits should be sofficient for all in-transit data to be flused from the system.

Take a look at this post for some additional info: Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems?

Upvotes: 2

Non-maskable Interrupt
Non-maskable Interrupt

Reputation: 3911

This is not a bug. Time Wait (and Close Wait) is by design for safety purpose. You may however adjust the wait time. In any case, on server's perspective the socket is closed and you are relax by the ulimit counter, it has not much visible impact unless you are doing stress test.

Upvotes: 2

Related Questions