英文:
inet_ntop returns address that doesnt exist
问题
#include <WinSock2.h>
#include <WS2tcpip.h>
#include "stdio.h"
int main(int argc, wchar_t *argv[]) {
// 初始化 Windows 套接字
int IResult = NULL;
WSADATA wsaDataStruct;
IResult = WSAStartup(MAKEWORD(2, 2), &wsaDataStruct);
if (IResult != 0) // 出错
{
printf("错误:Winsock2 初始化,%d", IResult);
return 1;
}
// 结果是 getaddrinfo 的输出,hints 是一个辅助结构
struct addrinfo*
result = NULL, // 地址的链表
* ptr = NULL,
hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// 主机名
char hostname[64] = {};
gethostname(hostname, 64);
IResult = getaddrinfo(hostname, "4500", &hints, &result);
if (IResult != 0) { // 发生了错误,获取错误信息
printf("错误:Winsock2 addrinfo,%d", IResult);
WSACleanup();
return 2;
}
// 循环处理地址
addrinfo* addr = result;
while (addr != nullptr)
{
char ip[16];
inet_ntop(addr->ai_family, addr->ai_addr, ip, 16);
printf("找到地址:%s", ip);
addr = addr->ai_next;
}
return 0;
}
我正在遍历 addrinfo
结构的链表,目前只返回一个结构,其中包含地址 2.0.17.148,而我的机器有一个本地地址 192.168.2.1。
我只有一个网络接口,而 addrinfo
返回一个有效的结构。
英文:
#include <WinSock2.h>
#include <WS2tcpip.h>
#include "stdio.h"
int main(int argc, wchar_t *argv[]) {
//init Windows Sockets
//IResult
int IResult = NULL;
WSADATA wsaDataStruct;
IResult = WSAStartup(MAKEWORD(2, 2), &wsaDataStruct);
if (IResult != 0) // Error
{
//printf u are fucked;
printf("Error: Winsock2 Init, %d", IResult);
return 1;
}
//Result is output of getaddrinfo, hints is a helper struct
struct addrinfo*
result = NULL, //Linked list of addresses
* ptr = NULL,
hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
//Hostname
char hostname[64] = {};
gethostname(hostname, 64);
IResult = getaddrinfo(hostname, "4500", &hints, &result);
if (IResult != 0) { //Smth bad happened get Error
printf("Error: Winsock2 addrinfo, %d", IResult);
WSACleanup();
return 2;
}
//Loop addresses
addrinfo* addr = result;
while (addr!=nullptr)
{
char ip[16];
inet_ntop(addr->ai_family, addr->ai_addr, ip, 16);
printf("Address found: %s", ip);
addr = addr->ai_next;
}
return 0;
}
I am looping through the linked list of addrinfo
structs and so far it returns one struct only which has an address of 2.0.17.148, while my machine has a local address of 192.168.2.1
I have only 1 network interface, and addrinfo
returns a valid struct.
答案1
得分: 2
inet_ntop
的参数应该是指向in_addr
(IPv4)或in6_addr
(IPv6)的指针。
您将其传递给了一个sockaddr
,对于IPv4将是sockaddr_in
,对于IPv6将是sockaddr_in6
。(因为您只请求使用AF_INET
获取IPv4地址,所以不会获得任何IPv6地址)。sockaddr包含了地址族代码、端口和地址信息。
要获取in_addr
,您需要在sockaddr_in
结构内访问它:首先将addr->ai_addr
强制转换为sockaddr_in*
,然后访问sin_addr
成员,然后获取指向它的指针。
inet_ntop(addr->ai_family, &((sockaddr_in*)addr->ai_addr)->sin_addr, ip, 16);
注意:这仅适用于IPv4(AF_INET地址族)。要支持IPv6,您需要检查地址族是否为AF_INET或AF_INET6,并在AF_INET6的情况下使用sockaddr_in6
,并为ip
分配更多的空间,因为IPv6地址更长。
英文:
inet_ntop
's argument should be a pointer to an in_addr
(IPv4) or an in6_addr
(IPv6).
You are passing it to a sockaddr
, which will be a sockaddr_in
for IPv4 or a sockaddr_in6
for IPv6. (You won't get any IPv6 addresses because you only asked for IPv4 addresses using AF_INET
). The sockaddr contains the family code, the port, and the address.
To get the in_addr
you need to access it within the sockaddr_in
structure: First cast addr->ai_addr
to sockaddr_in*
, then access the sin_addr
member, then get a pointer to it.
inet_ntop(addr->ai_family, &((sockaddr_in*)addr->ai_addr)->sin_addr, ip, 16);
Note: this only works for IPv4 (AF_INET family). To support IPv6 as well, you need to check whether the family is AF_INET or AF_INET6, and use sockaddr_in6
for AF_INET6, and allocate more space for ip
because the addresses are longer.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论