我开发了一个包含小型 http 服务器的应用程序。
我的应用程序在启动时启动。如果应用程序正常停止(etc/init.d/myappli stop),套接字将被关闭
close (socket_desc);
但如果我用 kill -9
杀死它,套接字将不会关闭
http 服务器代码:
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);
}
问题:
1) 如果程序被杀,如何关闭socket?
2)在这种情况下应该使用什么类型的套接字来避免套接字不会被另一个使用tcp套接字的进程使用?
最佳答案
如果你用kill -9
杀死一个程序,端口将 被关闭,不是被程序关闭,而是被操作系统关闭。它被关闭的事实正是使它可以被另一个进程接管的原因。
端口不是为特定程序“保留”的。程序死亡后唯一保留的端口是如果您不设置 SO_REUSEADDR
在这种情况下,它会保留给(从内存中)2 TIME_WAIT
句点。但是你在评论中告诉我们你做设置了SO_REUSEADDR
。这意味着“使该端口可用于下一个尝试监听它的程序”。它不区分该程序是相同程序还是不同程序。
我想你认为 SO_REUSEADDR
的意思是'这个程序可能想要重用端口,所以不要把它给其他人'。这绝对是 不是 SO_REUSEADDR
所做的。 SO_REUSEADDR
(广义地说,无论如何在 Unix 上)在你的程序死后立即释放端口供任何程序使用到操作系统,而不是等待一段时间。在 MS 上,它(有点奇怪)用于绑定(bind)到已经在使用的端口。如需更多信息,请参阅 Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems? - 但是请注意,在 no 操作系统上,这是否意味着我猜你认为它的意思。
关于当程序被 kill 命令停止时关闭 tcp 套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28280826/