如果一个客户端向服务器发送消息,则创建一个向所有客户端发送消息的服务器。我用telnet和计算机中的另外两个客户端测试了我的服务器。它可以在函数getaddrinfo的第一个参数中使用"localhost“作为值。BUt当我用我的ip地址替换它时,我在google上搜索得到它时,它没有将套接字绑定到端口。为什么会这样?
当我测试我的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地址--注意:我用"xx.xxx.xxx.xxx“替换了IP地址,程序就无法绑定
if ((rv = getaddrinfo("xx.xxx.xxx.xxx", PORT, &hints, &ai)) != 0) {
fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
exit(1);
}发布于 2015-04-10 12:53:44
最不寻常的是想要绑定到"localhost"或您的外部IP地址。当今时代的大多数计算机都没有外部IP地址(谷歌看到的),因为在它们和互联网之间有一个路由器和一个非军事区。如果您想向internet公开对LAN可见的服务,则需要配置路由器转发连接,这是一个更适合于堆栈溢出的网络变体的主题。
提供您的hints.ai_flags = AI_PASSIVE,您应该能够使用NULL代替"localhost",getaddrinfo将返回可以绑定到的所有合适接口的列表。如果您的hints.ai_flags不包含AI_PASSIVE,则无法保证您可以绑定返回的接口。如果您选择在这里使用字符串,AI_PASSIVE标志将被忽略。
在您的代码中,您将一个一个地创建多个套接字,在创建下一个套接字时丢弃先前创建的套接字。这是一个资源泄漏,也可能是您注意到的问题的原因。也许您打算将多个套接字描述符存储到数组中,并一次绑定它们?
一旦你完成了freeaddrinfo,不要忘了使用ai。在下面的示例中,我使用了PF_UNSPEC和SOCK_STREAM来侦听IPV4和IPV6接口(以及任何其他流类型),但是可以将它们更改为绑定到其他类型的地址。
#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);
/* ... */https://stackoverflow.com/questions/29561243
复制相似问题