【问题标题】:My linux application port is taken by another service when it's stopped我的 linux 应用程序端口在停止时被另一个服务占用
【发布时间】:2015-03-30 00:35:45
【问题描述】:

我开发了一个包含小型 http 服务器的应用程序。

我的应用程序在启动时启动。如果我杀死它(例如kill -9),http 服务器端口将直接被另一个守护进程(来自 Broadcom 的 acsd)占用。

我用 drop-bear 尝试了相同的行为,但问题没有重现。如果我杀死 drop-bear,则 acsd 不会占用它的端口。

在我的服务器代码之后:

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);
}

我的 http 服务器做错了什么?

【问题讨论】:

  • 您运行客户端/服务器的端口号是多少?你试过改变它吗?
  • 端口默认为51005
  • 你没有做错任何事。什么是落熊?
  • dropbear 是 linux 中的 ssh 服务器
  • 值得测试ascd 选择的端口是否与您的服务器相关:禁用启动时启动服务器,但保持ascd 启用;重启,查看ascd是否抢到了目标端口。另外,尝试为您的服务器分配一个您通常不会看到ascd 使用的端口,并测试您的服务器停止时ascd 是否获取它。

标签: c++ c linux sockets tcpsocket


【解决方案1】:

正如我在评论中所说,这可能是因为操作系统仍然从您的可执行文件中看到端口繁忙,因为您杀死了它并且它没有释放资源。

谷歌搜索了一下,我发现 this question 与您的问题相似。

现在,问题似乎不在于您的代码,而在于您如何管理杀戮..

尝试使用 kill 而不是 kill -9 或尝试捕获 sig 以便可执行文件能够自行释放其资源

【讨论】:

  • 所陈述的问题不是端口没有被清理,而是另一个进程直接抓住了它。这几乎表明当 OP 的服务器停止时端口 is 被释放。至少,操作系统看到不再有人在听。 SO_REUSEADDR 选项已启用,因此如果没有活动侦听器,则任何人都可以绑定。
  • 让我想到的是OP描述的系统行为。虽然 SO_REUSEADDR 确实允许任何人在端口释放后绑定端口,但它如何可能在释放端口后突然被占用?
  • 如果ascd 在 OP 的服务器停止后一直抢占该端口,那么它一定是 ascd 特别想要使用并积极尝试抢占的端口。观察到ascd 在其他服务被杀死时不会抓取与其他服务关联的端口,这一点得到了支持。
  • 底线是您的回答没有解决问题。操作系统确实没有看到端口仍然繁忙,这是问题的固有部分。
  • 但是是的,如果我已经正确分析了问题,那么选择一个既不ascd 也不任何其他正在运行的服务都不想使用的端口应该可以解决它。这实际上是与实施网络服务器相关的常规问题。
【解决方案2】:

因为我没有回答我的问题。我想与您分享对该问题的回应。

acsd 服务占用端口,因为套接字没有关闭并且设置了选项SO_REUSEADDR

【讨论】:

    最近更新 更多