The socket is opened after the process that opened it terminated

After closing the client socket on the server side and exiting the application, the socket is still open for a while.

I can see this through netstat

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

      

I am using log4cxx logging and telnet appender. log4cxx uses apr sockets. Socket :: close () method looks like this:

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 has been processed successfully. But after the program finishes, I can see the open socket via netstat, and if it starts up again, log4cxx cannot open port 6676 because it is busy. I am trying to change log4cxx. Closing the connector before closing:

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 that didn't help, the bug was still reproducible.

+3


source to share


3 answers


It's not a mistake. Waiting time (and closing) is design for security. However, you can adjust the timeout. In any case, from a server point of view, the nest closes and you relax with the ulimit counter, it has no discernible effect unless you do a stress test.



+2


source


As Calvin pointed out, this is not a mistake, it is a feature. Timeout is the state of a socket, which says that this socket is no longer in use, but it cannot be reused nonetheless.

Imagine that you have an open socket and some client is sending data. The data can be copied to the network or in flight when the server closes its socket.



Now, imagine you start a service again or start a new service. The packets on the wire don't know its new service and the service can't know that the packets are for the service that's gone. The new service might try to parse the packets and fail because they are in some odd format, or the client might get an unrelated error and keep trying to send, perhaps because the sequence numbers don't match and the receiving node will receive some odd error. On the expected wait, the client will be notified that the socket is closed and the server will not potentially receive odd data. Win-win. The expected time must be sufficient for all data in transit to be drained from the system.

Take a look at this post for more information: SO_REUSEADDR and SO_REUSEPORT Socket options, how are they different? Do they mean the same across all major operating systems?

+2


source


TIME_WAIT

is a socket state allowing all incoming packets that may remain from the connection to arrive or dead before the connection parameters (source address, source port, destination address, destination port) can be reused. The kernel simply sets a timer to wait for this time before allowing reuse of this socket. But you cannot shorten it (even if you can, you better not), because you have no way of knowing if packets are still traveling or speeding up or killing them. The only option you have is to wait until the socket is bound to this port before timeout and transition from state TIME_WAIT

to state CLOSED

.

If you were allowed to reuse a connection (I think there is an option or something in the linux kernel) and you get an old connection packet, you might get the connection reset due to the received packet. This can lead to more problems in the new connection. They are solved by making you wait until all traffic belonging to the old connection dies or reaches the target before using that socket again.

0


source







All Articles