Reputation: 3452
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
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
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:
Upvotes: 2