【问题标题】:Socket Error::Address Already In Use套接字错误::地址已在使用中
【发布时间】:2015-12-30 07:17:23
【问题描述】:

我正面临绑定到套接字的问题。 第一个实例正常工作,即 socket() 返回成功,因此返回 bind() 和 listen(),accept(),因此返回 recv() - 一切都很好。 绑定“地址已在使用”时,第二个实例抛出错误

我之前浏览过所有关于此的帖子,但我没有看到任何具体的解决方案。

我的代码如下:-

if((status = getaddrinfo(NULL,"8080",&hints,&servinfo))!=0){
        ALOGE("Socket:: getaddrinfo failed %s\n",strerror(errno));
        return NULL;
    }

    server_sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
    if(server_sockfd == -1) {
        ALOGE("Socket:: Scoket System Call failed %s\n",strerror(errno));
        return NULL;
    }

    if ((setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int))) < 0)
    {
        ALOGE("Socket:: setsockopt failed %s\n",strerror(errno));
        return NULL;
    }

    ret = bind(server_sockfd, servinfo->ai_addr,servinfo->ai_addrlen);
    if(ret!=0) {
        ALOGE("Socket:: Error Binding on socket %s\n",strerror(errno));
        return NULL;
    }

此代码运行在android平台上。

在打开新会话之前,我已正确关闭每个会话,如下所示:-

ret = shutdown(client_sockfd,0);
if(ret != 0)
    ALOGE("Socket:: Shutdown Called%s\n",strerror(errno));

我也尝试过关闭,但没有成功。

令人惊讶的是,即使我们在很长一段时间后尝试打开套接字,错误也不会消失(根据 TIME_WAIT 逻辑)

谁能指导我正确调用或 API 或逻辑(在代码中,而不是在命令行中,除了直接杀死进程)来处理这种情况吗?

【问题讨论】:

  • 您(错误地)关闭了已接受的客户端套接字,但您是否也在关闭侦听服务器套接字?您不能将新的 TCP 套接字绑定到以前的套接字仍绑定到的同一 IP/端口。您为什么首先尝试将多个套接字绑定到同一个 IP/端口?
  • 感谢您的 cmets。是的,我在客户端和服务器套接字中都调用了 close。其背后的逻辑是我的服务器线程是启动的应用程序的一部分,并且基于成功启动我创建服务器线程。即使在我的应用程序关闭后,该线程也不必不必要地处于活动状态。为了处理这种情况,我试图调用我的 pthread_exit 时关闭套接字。就客户而言,我认为当客户完成其工作时调用 close 是可以的。如果我的逻辑看起来不正确,请纠正我。
  • 您显然没有正确关闭所有内容。有些东西仍然是开放的。请提供Minimal, Complete, and Verifiable example 说明您如何管理所有套接字。
  • server_sockfd 上调用close() 的代码在哪里?在client_sockfd 上调用close() 的代码在哪里?同样,请提供MCVE 显示与您的套接字相关的所有相关代码。
  • 谢谢@RemyLebeau 我想我有问题。我正在关闭从 accept() 获得的服务器套接字 fd,但没有关闭服务器实际的 socket() fd 现在它似乎可以工作了。感谢你的信息。将保持不张贴礼仪。

标签: sockets


【解决方案1】:

套接字是两台计算机之间通过网络在特定端口上进行通信的一半通道。 (另一半是另一台电脑上对应的socket)

我想在这种情况下错误很明显。如Address already in use 所述,因此您在第二次尝试中尝试连接的套接字已被使用(端口已被占用)-> 可能是由于第一次套接字连接。

要进一步调查,请检查另一个 SO question herehere

【讨论】:

  • 谢谢。正如我所提到的,确实错误很清楚。但我想重新使用相同的端口,即使在尝试重新打开它之前调用 close(以及 shutdown())之后我也无法使用。最重要的是close()第一次没有返回任何错误。如果关闭失败,那么关闭应该抛出请求的fd无法关闭的错误。因此我的查询。
  • @user5729621 你能把代码 sn-p 贴在你关闭之前打开的套接字的地方吗?
  • 我已经发布了相同的内容。我的意思是我尝试了关闭 Api 和关闭 Api,但是下一次 bind 迭代给出了错误。我也尝试过使用另一个端口号,但它抛出了同样的错误
  • @user5729621 难以置信。如果您使用不同的端口号,您应该会成功,除非其他东西已经绑定到该端口。您尝试绑定到哪个 IP:port?
【解决方案2】:

即使使用 SO_REUSEADDR,您也无法在两个进程之间共享 TCP 侦听端口。

NB shutdown() 不会关闭 TCP 会话。它半关闭它。您必须关闭套接字。

【讨论】:

  • OP 说:“我也尝试过关闭,但没有成功。
  • @RemyLebeau 确实如此。很难理解他为什么要使用shutdown(),以及为什么他一开始就不使用close()
猜你喜欢
  • 2015-05-26
  • 2016-09-22
  • 1970-01-01
  • 2013-07-01
  • 2018-01-30
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多