2

我开发了一个包含小型 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)如果程序被杀死,如何关闭套接字?

2)在这种情况下应该使用什么类型的套接字以避免套接字不会被另一个使用tcp套接字的进程使用?

4

2 回答 2

6

如果你用kill -9端口杀死一个程序,不是由程序关闭,而是由操作系统关闭。它被关闭的事实正是使它可以被另一个进程接管的原因。

端口不是为特定程序“保留”的。程序终止后唯一的端口保留是如果您没有设置SO_REUSEADDR,在这种情况下它会保留(从内存中)2 个TIME_WAIT周期。但是你已经在你设置的评论中告诉我们SO_REUSEADDR。这意味着“使该端口可用于下一个尝试侦听它的程序”。它不区分该程序是相同程序还是不同程序。

我认为您认为这SO_REUSEADDR意味着“该程序可能希望重用该端口,因此不要将其提供给其他任何人”。那绝对不是什么SO_REUSEADDRSO_REUSEADDR(从广义上讲,无论如何在 Unix 上)在您的程序死后立即释放端口以供任何程序使用到操作系统,而不是等待一段时间。在 MS 上,它(有点奇怪)用于绑定到已经在使用的端口。有关详细信息,请参阅套接字选项 SO_REUSEADDR 和 SO_REUSEPORT,它们有何不同?它们在所有主要操作系统中的含义都相同吗?- 但是请注意,在任何操作系统上,这是否意味着我猜你认为它意味着什么。

于 2015-02-02T15:54:17.233 回答
0

您的问题是旧套接字在TIME_WAIT释放前不久将处于状态。如果你想减少在TIME_WAIT状态中花费的时间,你可以减少逗留时间。请注意,过度减少它会带来风险。

您可以使用 更改套接字的逗留时间setsockopt(2)

相关链接:

终极 SO_LINGER 页面

TCP 选项 SO_LINGER(零)

于 2015-02-02T16:35:10.820 回答