inet_ntop返回不存在的地址。

huangapple go评论62阅读模式
英文:

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 &lt;WinSock2.h&gt;
#include &lt;WS2tcpip.h&gt;
#include &quot;stdio.h&quot;

int main(int argc, wchar_t *argv[]) {

	//init Windows Sockets
	//IResult
	int IResult = NULL;
	WSADATA wsaDataStruct;
	IResult = WSAStartup(MAKEWORD(2, 2), &amp;wsaDataStruct);
	if (IResult != 0) // Error
	{
		//printf u are fucked;
		printf(&quot;Error: Winsock2 Init, %d&quot;, 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, &quot;4500&quot;, &amp;hints, &amp;result);
	if (IResult != 0) { //Smth bad happened get Error
		printf(&quot;Error: Winsock2 addrinfo, %d&quot;, IResult);
		WSACleanup();
		return 2;
	}

	//Loop addresses
	addrinfo* addr = result;
	while (addr!=nullptr)
	{
		char ip[16];
		inet_ntop(addr-&gt;ai_family, addr-&gt;ai_addr, ip, 16);
		printf(&quot;Address found: %s&quot;, ip);
		addr = addr-&gt;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-&gt;ai_addr to sockaddr_in*, then access the sin_addr member, then get a pointer to it.

inet_ntop(addr-&gt;ai_family, &amp;((sockaddr_in*)addr-&gt;ai_addr)-&gt;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.

huangapple
  • 本文由 发表于 2020年1月3日 23:21:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/59581083.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定