gpt4 book ai didi

c - 为什么无法绑定(bind)到指定IP地址的端口,但在localhost上却可以正常工作?

转载 作者:行者123 更新时间:2023-11-30 15:21:27 25 4
gpt4 key购买 nike

我正在创建一台服务器,如果一个客户端向服务器发送消息,该服务器就会向所有客户端发送消息。我使用 telnet 和计算机中的其他两个客户端测试了我的服务器。如果我在函数 getaddrinfo 的第一个参数中使用“localhost”作为值,它会起作用。但是当我将其替换为我通过谷歌搜索获得的IP地址时,它无法将套接字绑定(bind)到端口。为什么会发生这种情况?

当我测试我的 telnet 时,这效果很好。

if ((rv = getaddrinfo("localhost", PORT, &hints, &ai)) != 0) {
fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
exit(1);
}

for(p = ai; p != NULL; p = p->ai_next) {
listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (listener < 0) {
continue;
}

// lose the pesky "address already in use" error message
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) {
close(listener);
continue;
}

break;
}

如果我指定了 IP 地址,程序将无法绑定(bind)注意:我将 IP 地址替换为“xx.xxx.xxx.xxx”

if ((rv = getaddrinfo("xx.xxx.xxx.xxx", PORT, &hints, &ai)) != 0) { 
fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
exit(1);
}

最佳答案

想要绑定(bind)到“localhost”或外部IP地址是最不寻常的。如今,大多数计算机都没有外部 IP 地址(Google 看到的地址),因为它们和互联网之间有一个路由器和一个非军事区。如果您想将 LAN 可见的服务公开到互联网,那么您需要将路由器配置为转发连接,这是一个更适合 Stack Overflow 网络变体的主题。

提供您的 hints.ai_flags = AI_PASSIVE,您应该能够使用 NULL 代替 "localhost"getaddrinfo 将返回您可以绑定(bind)的所有合适接口(interface)的列表。如果您的 hints.ai_flags 不包含 AI_PASSIVE,则无法保证您可以绑定(bind)返回的接口(interface)。如果您选择在此处使用字符串,AI_PASSIVE 标志无论如何都会被忽略...

在您的代码中,您将一个接一个地创建多个套接字,并在创建下一个套接字时丢弃先前创建的套接字...这是资源泄漏,也可能是您注意到的问题的原因。也许您打算将多个套接字描述符存储到一个数组中,并一次绑定(bind)它们一个?

使用完 ai 后,不要忘记freeaddrinfo。在下面的示例中,我使用 PF_UNSPECSOCK_STREAM 来监听 IPV4 和 IPV6 接口(interface)(以及任何其他流类型),但这些可以更改为绑定(bind)到其他类型的地址。

#define BIND_ADDR NULL
#define BIND_PORT "1234"

struct addrinfo *ai;
int rv = getaddrinfo(BIND_ADDR,
BIND_PORT,
&(struct addrinfo){ .ai_family = PF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_flags = AI_PASSIVE },
&ai)
if (rv != 0) {
fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
exit(1);
}

size_t ai_size = 0;
for (struct addrinfo *a = ai; a != NULL; a = a->ai_next) {
ai_size++;
}

int socket[ai_size] = { 0 };
size_t x = 0;
for (struct addrinfo *a = ai; a != NULL; a = a->ai_next) {
socket[x++] = socket(a->ai_family, a->ai_socktype, a->ai_protocol);
/* ... */
}

freeaddrinfo(ai);
/* ... */

关于c - 为什么无法绑定(bind)到指定IP地址的端口,但在localhost上却可以正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29561243/

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