我正在使用USB Internet加密狗,为我的计算机分配IPv6地址。当我使用onClicked: list.currentIndex += 1
时,我可以看到分配的IPv6地址,它是一个公共IP。
当我使用GetAdaptersAddresses()
时,我得到一个包含任意广播,多播和单播地址的长链表,但它们都不匹配系统的IP地址。
还有其他地方可以获得系统的IP吗?我实际上想要获取系统的IP地址,以便我可以将它绑定到套接字。
我使用的是Windows 7。
touch
如您所见,没有一个地址与命令提示符中的地址匹配。
答案 0 :(得分:2)
我发现您的代码存在许多问题:
调用GetAdaptersAddresses()
时,您没有执行足够的错误处理。
您正在泄露您分配的第一个IP_ADAPTER_ADDRESSES
结构。
您没有将tp->Length
输出到while (tp)
循环顶部的控制台。
您没有正确检索和格式化IP地址!
最后一点是你问题的根源。
当您尝试从列表中检索IP地址时,您正在错误地访问sockaddr_X
结构。
此代码:
sockaddr_in *si = (sockaddr_in *)&(pu->Address.lpSockaddr);
sockaddr_in6 *si = (sockaddr_in6 *)&(pu->Address.lpSockaddr);
需要这样:
sockaddr_in *si = (sockaddr_in *)(pu->Address.lpSockaddr);
sockaddr_in6 *si = (sockaddr_in6 *)(pu->Address.lpSockaddr);
lpSockaddr
字段已经指向sockaddr_X
结构的指针,因此您需要输入该指针值,不要使用&
运算符获取该指针本身的地址,您将输入错误的内存地址,因此您尝试为IP地址格式化的二进制数据是垃圾!
您还错误地致电inet_ntop()
。它期望指向in_addr
/ in6_addr
结构的指针作为输入,但是您将向它传递指向sockaddr_in
/ sockaddr_in6
结构的指针。所以格式化的输出字符串也是垃圾!
此代码:
inet_ntop(AF_INET, si, a, sizeof(a));
inet_ntop(AF_INET6, si, a, sizeof(a));
需要这样:
inet_ntop(AF_INET, &(si->sin_addr), a, sizeof(a));
inet_ntop(AF_INET6, &(si->sin6_addr), a, sizeof(a));
您正在为链接列表中的所有任播,单播,多播,DNS服务器和网关IP地址犯下这两个错误。
话虽如此,尝试更像这样的事情:
// getadaptersinfo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <WinSock2.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>
#include <iostream>
#pragma comment(lib,"IPHLPAPI.lib")
#pragma comment(lib,"Ws2_32.lib")
using namespace std;
void displayAddress(const SOCKET_ADDRESS &Address)
{
cout << "\n Length of sockaddr: " << Address.iSockaddrLength;
if (Address.lpSockaddr->sa_family == AF_INET)
{
sockaddr_in *si = (sockaddr_in *)(Address.lpSockaddr);
char a[INET_ADDRSTRLEN] = {};
if (inet_ntop(AF_INET, &(si->sin_addr), a, sizeof(a)))
cout << "\n IPv4 address: " << a;
}
else if (Address.lpSockaddr->sa_family == AF_INET6)
{
sockaddr_in6 *si = (sockaddr_in6 *)(Address.lpSockaddr);
char a[INET6_ADDRSTRLEN] = {};
if (inet_ntop(AF_INET6, &(si->sin6_addr), a, sizeof(a)))
cout << "\n IPv6 address: " << a;
}
}
int main()
{
cout << "\nUsing GetAdaptersAddresses";
ULONG size = 1024 * 15;
PIP_ADAPTER_ADDRESSES p = (IP_ADAPTER_ADDRESSES*) HeapAlloc(GetProcessHeap(), 0, size);
if (!p)
{
cout << "\nCannot allocate memory";
cin.get();
return -1;
}
ULONG ret;
do
{
ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, p, &size);
if (ret != ERROR_BUFFER_OVERFLOW)
break;
PIP_ADAPTER_ADDRESSES newp = (IP_ADAPTER_ADDRESSES*) HeapReAlloc(GetProcessHeap(), 0, p, size);
if (!newp)
{
cout << "\nCannot reallocate memory";
HeapFree(GetProcessHeap(), 0, p);
cin.get();
return -1;
}
p = newp;
}
while (true);
if (ret != NO_ERROR)
{
cout << "\nSomething went wrong. Error: " << ret;
HeapFree(GetProcessHeap(), 0, p);
cin.get();
return -1;
}
int i = 0;
for(PIP_ADAPTER_ADDRESSES tp = p; tp != NULL; tp = tp->Next)
{
++i;
cout << "\nLength of IP Adapter info: " << tp->Length;
cout << "\n IPv4 IfIndex: " << tp->IfIndex;
cout << "\n Adapter name: " << tp->AdapterName;
cout << "\n Unicast addresses:";
int j = 0;
for (PIP_ADAPTER_UNICAST_ADDRESS pu = tp->FirstUnicastAddress; pu != NULL; pu = pu->Next)
{
++j;
displayAddress(pu->Address);
}
cout << "\n # of Unicast addresses: " << j;
cout << "\n Anycast addresses:";
j = 0;
for (PIP_ADAPTER_ANYCAST_ADDRESS pa = tp->FirstAnycastAddress; pa != NULL; pa = pa->Next)
{
++j;
displayAddress(pa->Address);
}
cout << "\n # of Anycast addresses: " << j;
cout << "\n Multicast addresses:";
j = 0;
for (PIP_ADAPTER_MULTICAST_ADDRESS pm = tp->FirstMulticastAddress; pm != NULL; pm = pm->Next)
{
++j;
displayAddress(pm->Address);
}
cout << "\n # of Multicast addresses: " << j;
cout << "\n DNS server addresses:";
j = 0;
for (PIP_ADAPTER_DNS_SERVER_ADDRESS pd tp->FirstDnsServerAddress; pd != NULL; pd = pd->Next)
{
++j;
displayAddress(pd->Address);
}
cout << "\n # of DNS server addresses: " << j;
cout << "\n Gateway addresses:";
j = 0;
for (PIP_ADAPTER_GATEWAY_ADDRESS_LH pg = tp->FirstGatewayAddress; pg != NULL; pg = pg->Next)
{
++j;
displayAddress(pg->Address);
}
cout << "\n # of Gateway addresses: " << j;
cout << "\n DNS suffix" << tp->DnsSuffix;
cout << "\n Description" << tp->Description;
cout << "\n Friendly name" << tp->FriendlyName;
if (tp->PhysicalAddressLength != 0)
{
cout << "\n Physical address: ";
cout << std::hex << (int)tp->PhysicalAddress[0];
for (UINT i = 1; i < tp->PhysicalAddressLength; i++)
cout << "-" << std::hex << (int)tp->PhysicalAddress[i];
}
cout << "\n Flags" << tp->Flags;
cout << "\n MTU" << tp->Mtu;
cout << "\n IfType" << tp->IfType;
cout << "\n OperStatus" << tp->OperStatus;
cout << "\n IPv6 IfIndex :" << tp->Ipv6IfIndex;
cout << "\n and more...";
}
cout << "\n# of IP Adapters: " << i;
HeapFree(GetProcessHeap(), 0, p);
cin.get();
return 0;
}
答案 1 :(得分:-1)
此代码:
sockaddr_in *si = (sockaddr_in *)&(pu->Address.lpSockaddr);
sockaddr_in6 *si = (sockaddr_in6 *)&(pu->Address.lpSockaddr);
需要变成这样:
sockaddr_in *si = ((sockaddr_in *)pu->Address.lpSockaddr);
sockaddr_in6 *si = ((sockaddr_in6 *)pu->Address.lpSockaddr);