gpt4 book ai didi

c++ - 绑定(bind)()错误 98 - "Address already in use"

转载 作者:行者123 更新时间:2023-12-03 07:51:33 25 4
gpt4 key购买 nike

如果我在 Linux 上启动本地服务器,我会收到“地址已在使用中”错误。

我使用setsockopt(SO_REUSEADDR),但它没有帮助。我怎么解决这个问题?代码:

#include <iostream>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
using namespace std;

int main() {
sockaddr_un s_addr;
s_addr.sun_family = AF_UNIX;
strcpy(s_addr.sun_path, "server");

int s_descriptor = socket(AF_UNIX, SOCK_STREAM, 0);

const int par = 1;
if (setsockopt(s_descriptor, SOL_SOCKET, SO_REUSEADDR, &par, sizeof(int)) < 0){
cout << "Error setsockopt()";
return -1;
}

if (bind(s_descriptor, (sockaddr *)&s_addr, sizeof(s_addr)) < 0) {
cout << "Error with bind()\n";
cout << strerror(errno);
return -2;
}

close(s_descriptor);
return 0;
}

最佳答案

您正在尝试创建AF_UNIX套接字。 AF_UNIX 套接字创建一个文件系统管道节点来处理连接。

在这种情况下,EADDRINUSE 意味着文件系统节点已经存在。实际上可能没有什么东西在监听它,但它确实存在,并且 bind() 由于这个原因而失败。这是 AF_UNIX 套接字工作方式的一个怪癖。 SO_REUSEADDR 适用于 AF_INETAF_INET6 套接字,对于 AF_UNIX 套接字没有太多作用。

strcpy(s_addr.sun_path, "server");

您会惊讶地发现当前目录中有一个server特殊管道文件。这就是罪魁祸首。解决办法很简单:

unlink("server");

就在您bind()之前,现在您可以绑定(bind)它。

如果您一直在关注,您现在会想知道是否有任何事情会阻止服务器的多个实例启动、创建和 bind() 到此 AF_UNIX 套接字,并粗鲁地取消其前身的监听套接字的链接,为您留下服务器进程的多个实例,除了其中一个之外,所有实例现在都完全无用了。这是正确的,没有什么可以阻止你这样做。

这就是为什么 AF_UNIX 服务器通常会采用其他方法来确保只有一个实例在运行,例如单独的锁定文件。但这将是一个单独的问题......

关于c++ - 绑定(bind)()错误 98 - "Address already in use",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76945130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com