当程序被 kill 命令停止时关闭 tcp 套接字

标签 c sockets tcpsocket

我开发了一个包含小型 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/

相关文章:

c++ - 矩阵乘法在 C++ 中不起作用

javascript - 单个应用程序中的 Dotcloud www 和 TCP -

c# - 从所有套接字接收消息而不循环遍历所有套接字

c - 为什么 printf ("%d"+1) 的输出是 d 而 printf ("%%%d"+1) 是 %d?

c - 在 Nintendo DS 上编程

java - C:将二维 double 组转换为java二维 double 组

java - ReadLine 不等待输入

node.js - 通过letscrypt设置https后Nodejs聊天程序 'io is not defined'错误

c++ - 移动 Boost asio TCP 流

c++ - 通过 TCP 套接字发送 XDR 的好方法