关于inet_pton(地址转网络)和inet_ntop(网络转地址)两个函数的使用
头文件:
windows下:
#include <WS2tcpip.h>
linux下:
#include <sys/socket.h>
#include <netinet/in.h>
#include<arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
af = AF_INET(IPV4) 或者 AF_INET6(IPV6)
src为指向字符型的地址(即IPV4或者IPV6的地址) ,将该地址转换为in_addr或者in6_addr(IPV6),复制在*dst中。
如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0。
char sIP[128] 为IP地址
inet_pton(AF_INET, sIP, (void *)&addr); // struct in_addr addr
inet_pton(AF_INET6, sIP, (void *)&addr); //struct in6_addr addr
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
af = AF_INET(IPV4) 或者 AF_INET6(IPV6)
src为指向字符型的地址(即IPV4或者IPV6的地址) ,将该地址转换为sockaddr_in或者sockaddr_in6(IPV6),复制在*dst中。
参数的作用和inet_pton相同,只是多了一个参数socklen_t cnt,他是所指向缓存区dst的大小,避免溢出。
inet_ntop函数成功的话返回字符串的首地址,错误返回NULL;
char sIP[128] 存转换的IP地址
inet_ntop(AF_INET, &(addr->sin_addr), sIP, sizeof(sIP)); //struct sockaddr_in *addr
inet_ntop(AF_INET, &(addr->sin6_addr), sIP, sizeof(sIP)); // struct sockaddr_in6 *addr
或者
inet_ntop(AF_INET, &(addr), sIP, sizeof(sIP));// struct in_addr addr
inet_ntop(AF_INET, &(addr), sIP, sizeof(sIP));//struct in6_addr addr
获取IP,网卡等相关网络信息
ULONG WINAPI GetAdaptersAddresses(
__in ULONG Family,
__in ULONG Flags,
__in PVOID Reserved,
__inout PIP_ADAPTER_ADDRESSES AdapterAddresses,
__inout PULONG SizePointer
);
头文件 库引用
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")
第一参数:
Value Meaning
AF_UNSPEC 0 Return both IPv4 and IPv6 addresses associated with adapters with IPv4 or IPv6 enabled.
AF_INET 2 Return only IPv4 addresses associated with adapters with IPv4 enabled.
AF_INET6 23 Return only IPv6 addresses associated with adapters with IPv6 enabled.
其他参数查看该链接https://www.dotblogs.com.tw/larrynung/2012/01/13/65678
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
ULONG outBufLen = 0;
GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &outBufLen); // 取结构体长度
DWORD dwRetVal = 0;
pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen);
do
{
pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen);
if (pAddresses == NULL)
break;
dwRetVal = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL, pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW)
{
free(pAddresses);
pAddresses = NULL;
}
else
break;
} while (dwRetVal == ERROR_BUFFER_OVERFLOW);
if (dwRetVal == NO_ERROR)
{
pCurrAddresses = pAddresses;
while ((pCurrAddresses != NULL) && (nFlags == 0))
{
pUnicast = pCurrAddresses->FirstUnicastAddress; //IP
if (pCurrAddresses->OperStatus != IfOperStatusUp)
{
pCurrAddresses = pCurrAddresses->Next;
continue;
}
int i = 1;
while (pUnicast && (nFlags == 0))
{
char sIP[130] = { 0 };
if (AF_INET == pUnicast->Address.lpSockaddr->sa_family)// IPV4 地址
inet_ntop(AF_INET,
&(((sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr),
sIP, sizeof(sIP));
else if (AF_INET6 == pUnicast->Address.lpSockaddr->sa_family)// IPV6 地址
inet_ntop(AF_INET6,
&(((sockaddr_in6*)pUnicast->Address.lpSockaddr)->sin6_addr),
sIP, sizeof(sIP));
if (strcmp(ipaddress, sIP) == 0)
{
CString mac;// MAC 地址的长度存在 PhysicalAddressLength
// 按格式输出
mac.Format(_T("%02X%02X%02X%02X%02X%02X"),
pCurrAddresses->PhysicalAddress[0],
pCurrAddresses->PhysicalAddress[1],
pCurrAddresses->PhysicalAddress[2],
pCurrAddresses->PhysicalAddress[3],
pCurrAddresses->PhysicalAddress[4],
pCurrAddresses->PhysicalAddress[5]);
nFlags = 1;
strcpy(name, mac);
break;
}
pUnicast = pUnicast->Next;
}
pCurrAddresses = pCurrAddresses->Next;
}
}
else
{
CString s;
s.Format(_T("GetAdaptersAddresses failed,error code:%d"), GetLastError());
}
if (pAddresses)
free(pAddresses);