【发布时间】:2019-09-20 10:06:33
【问题描述】:
我正在使用我找到的一些代码,我正在尝试理解其中的 for 循环 逻辑。
似乎没有使用 for 循环,而且它总是会中断。所以我不明白从 getaddrinfo() 返回什么样的信息会导致它再次循环并检查一些东西?
问题:基本上这个 for 循环试图完成什么?在我看来,它只是检查 list 不为 NULL,因为永远不会发生循环。
tcp_ctx* tcp_new_ctx(INT family, CHAR *host, CHAR *port) {
struct addrinfo *list = NULL;
struct addrinfo *e = NULL;
struct addrinfo hints;
tcp_ctx *c = NULL;
WSADATA wsa;
INT on = 1;
WSAStartup(MAKEWORD(2, 0), &wsa);
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// try to resolve network address for host
//list contains linked list of addrinfo structs containing information on the host
if (getaddrinfo(host, port, &hints, &list) != 0) {
return NULL;
}
c = tcp_alloc(sizeof(tcp_ctx));
// Traverse linked list from getaddr info
for (e = list; e != NULL; e = e->ai_next) {
if (family == AF_INET) {
memcpy(&c->v4, e->ai_addr, e->ai_addrlen);
c->ai_addr = (SOCKADDR*)&c->v4;
} else if (family == AF_INET6) {
memcpy(&c->v6, e->ai_addr, e->ai_addrlen);
c->ai_addr = (SOCKADDR*)&c->v6;
} else {
return NULL;
}
c->ai_addrlen = e->ai_addrlen;
// create socket and event for signalling
c->s = socket(family, SOCK_STREAM, IPPROTO_TCP);
if (c->s != SOCKET_ERROR) {
// ensure we can reuse same port later
setsockopt(c->s, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&on, sizeof(on));
}
break;
}
freeaddrinfo(list);
return c;
}
【问题讨论】:
-
循环看起来介于多余和损坏之间。 (它只关心第一个地址。如果第一个地址不是 IPv4 或 IPv6,代码就会中断……但这在当今的互联网上是极不可能的。)
-
FWIW,我同意你的观点,
for语句除了验证list不等于NULL之外什么都不做。如果目标是查找 IPv4 地址,同时跳过 IPv6 地址,则该循环是有意义的。但这不是循环正在做的事情。 -
列表中有什么?其他 IP 地址到它执行 getaddrinfo() 的地址?如果我了解 getaddrinfo() 应该返回的列表与多个链接的样子,那么我可能会解决这个问题。但是我不确定。