Anis_Stack
Anis_Stack

Reputation: 3452

close tcp socket when the program was stopped by kill command

I developed an application which contains a small http server.

my application is launched in the boot. if the application is stopped normally (etc/init.d/myappli stop) the socket will be closed

close (socket_desc); 

but if I kill it with kill -9 the socket will not be closed

http server code :

void http_server_init(void)
{
    struct sockaddr_in server;
    int cr_port;

    for(;;) {
        cr_port = conf.port;
        int i = (DEFAULT_PORT == cr_port)? 1 : 0;
        //Create socket
        cr_socket_desc = socket(AF_INET , SOCK_STREAM , 0);
        if (cr_socket_desc == -1)
        {
            LOG (ERROR,"Could not open server socket, Error no is : %d, Error description is : %s", errno, strerror(errno));
            sleep(1);
            continue;
        }

        /* enable SO_REUSEADDR */
        int reusaddr = 1;
        if (setsockopt(cr_socket_desc, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0) {
            LOG (WARNING,"setsockopt(SO_REUSEADDR) failed");
        }

        //Prepare the sockaddr_in structure
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        for(;;i++) {
            server.sin_port = htons(cr_port);
            //Bind
            if( bind(cr_socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
            {
                //print the error message
                LOG (ERROR,"Could not bind server socket on the port %d, Error no is : %d, Error description is : %s", cr_port, errno, strerror(errno));
                cr_port = DEFAULT_PORT + i;
                LOG (INFO,"Trying to use another port: %d", cr_port);
                continue;
            }
            break;
        }
        break;
    }
    LOG (INFO,"server initiated with the port: %d", cr_port);
}

Questions:

1) How to close socket if the program was killed?

2)And what is the type of socket should be used in this case to avoid that the socket will not be used by another process using tcp socket?

Upvotes: 4

Views: 7272

Answers (2)

abligh
abligh

Reputation: 25179

If you kill a program with kill -9 the port will be closed, not by the program, but by the operating system. The fact it is being closed is precisely what is making it available for being taken over by another process.

Ports are not 'reserved' for particular programs. The only reservation of ports after the death of the program is if you don't set SO_REUSEADDR in which case it's reserved for (from memory) 2 TIME_WAIT periods. But you've told us in the comments you do set SO_REUSEADDR. What that means is 'make the port available to the next program that tries to listen on it'. It doesn't differentiate between that program being the same program or a different one.

I think you think that SO_REUSEADDR means 'this program may want to reuse the port so don't give it to anyone else'. That is categorically not what SO_REUSEADDR does. SO_REUSEADDR (broadly speaking, and on Unix anyway) releases the port for use by any program to the operating system immediately after your program dies, as opposed to waiting for a while. On MS it is (somewhat bizarrely) used to bind to a port that's already in use. For more information, see Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems? - however note that on no operating system does it mean what I'm guessing you think it means.

Upvotes: 9

Klas Lindb&#228;ck
Klas Lindb&#228;ck

Reputation: 33283

Your problem is that the old socket will be in TIME_WAIT state a short while before it is released. If you want to reduce the time spent in the TIME_WAIT state you can reduce the linger time. Note that there are risks attached to reducing it too much.

You can change the linger time for your socket using setsockopt(2).

Related links:

The ultimate SO_LINGER page

TCP option SO_LINGER (zero)

Upvotes: 2

Related Questions