对getaddrinfo 函数进行测试:
在Windows和Linux环境下,IPv4的地址返回与输入均保持一致。
在Windows环境下,IPv6地址返回的ai_family值为23,而在Linux下则为10。
对于输入IP为 ::和::0 的情况,这两个环境返回的IP值均被置为 ::。
Windows环境解析Linux的IPv6地址格式:fe80::20c:29ff:fed5:82f%ens33 失败,
而Linux环境解析Windows的IPv6地址格式:fe80::59d8:5d6d:25cc:42cf%14 成功。
#include
#include
#include
#ifdef WINDOWS #include
#pragma comment(lib,"ws2_32.lib") #endif // WINDOWS #ifdef LINUX #include
#include
#endif // LINUX using namespace std; int ParseSockAddr(const struct sockaddr* addr, string& ip, int& port) { void* numeric_addr = nullptr; if (AF_INET == addr->sa_family) { numeric_addr = &((struct sockaddr_in*)addr)->sin_addr; port = ntohs(((struct sockaddr_in*)addr)->sin_port); } else if (AF_INET6 == addr->sa_family) { numeric_addr = &((struct sockaddr_in6*)addr)->sin6_addr; port = ntohs(((struct sockaddr_in6*)addr)->sin6_port); } else { return -1; } char addr_buff[INET6_ADDRSTRLEN]; if (inet_ntop(addr->sa_family, numeric_addr, addr_buff, sizeof(addr_buff)) == nullptr) return -1; ip = addr_buff; return 0; } void PrintAddr(const struct addrinfo* addr) { printf("ai_flags:[%d], ai_family[%d], ai_socktype[%d], ai_protocol[%d], ai_addrlen[%d], ai_canonname[%s]\n", addr->ai_flags, addr->ai_family, addr->ai_socktype, addr->ai_protocol, addr->ai_addrlen, addr->ai_canonname); string ip; int port = 0; auto ret = ParseSockAddr(addr->ai_addr, ip, port); printf("ParseSockAddr: ret[%d], Address<%s|%d>\n", ret, ip.c_str(), port); } int main() { #ifdef WINDOWS cout << "ON WINDOWS" << endl; WSADATA initData; initData.wVersion = 0; initData.wHighVersion = 2; memset(initData.szDescription, 0, sizeof(initData.szDescription)); memset(initData.szSystemStatus, 0, sizeof(initData.szSystemStatus)); initData.iMaxSockets = 100; initData.lpVendorInfo = nullptr; if (WSAStartup(2, &initData) != 0) { std::cout << "SocketInit Failed!" << std::endl; } #endif #ifdef LINUX cout << "ON LINUX" << endl; #endif set
ips = { "::", "::0","::1", "fe80::20c:29ff:fed5:82f","fe80::20c:29ff:fed5:82f%ens33", "fe80::59d8:5d6d:25cc:42cf%14", "0.0.0.0", "127.0.0.1","192.168.137.129" }; addrinfo hints, * res; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_IP; auto port = "10000"; cout << endl; for (auto& ip : ips) { auto ret = getaddrinfo(ip.c_str(), port, &hints, &res); printf("getaddrinfo: ret[%d], SrcAddress:<%s|%s>\n", ret, ip.c_str(), port); while (res != nullptr) { PrintAddr(res); res = res->ai_next; } cout << endl; } cout << endl; return 0; }
Windows输出:
ON WINDOWS getaddrinfo: ret[0], SrcAddress:<0.0.0.0|10000> ai_flags:[4], ai_family[2], ai_socktype[1], ai_protocol[0], ai_addrlen[16], ai_canonname[(null)] ParseSockAddr: ret[0], Address<0.0.0.0|10000> getaddrinfo: ret[0], SrcAddress:<127.0.0.1|10000> ai_flags:[4], ai_family[2], ai_socktype[1], ai_protocol[0], ai_addrlen[16], ai_canonname[(null)] ParseSockAddr: ret[0], Address<127.0.0.1|10000> getaddrinfo: ret[0], SrcAddress:<192.168.137.129|10000> ai_flags:[4], ai_family[2], ai_socktype[1], ai_protocol[0], ai_addrlen[16], ai_canonname[(null)] ParseSockAddr: ret[0], Address<192.168.137.129|10000> getaddrinfo: ret[0], SrcAddress:<::|10000> ai_flags:[4], ai_family[23], ai_socktype[1], ai_protocol[0], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address<::|10000> getaddrinfo: ret[0], SrcAddress:<::0|10000> ai_flags:[4], ai_family[23], ai_socktype[1], ai_protocol[0], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address<::|10000> getaddrinfo: ret[0], SrcAddress:<::1|10000> ai_flags:[4], ai_family[23], ai_socktype[1], ai_protocol[0], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address<::1|10000> getaddrinfo: ret[0], SrcAddress:
ai_flags:[4], ai_family[23], ai_socktype[1], ai_protocol[0], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address
getaddrinfo: ret[11001], SrcAddress:
getaddrinfo: ret[0], SrcAddress:
ai_flags:[4], ai_family[23], ai_socktype[1], ai_protocol[0], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address
Linux输出:
ON LINUX getaddrinfo: ret[0], SrcAddress:<0.0.0.0|10000> ai_flags:[1], ai_family[2], ai_socktype[1], ai_protocol[6], ai_addrlen[16], ai_canonname[(null)] ParseSockAddr: ret[0], Address<0.0.0.0|10000> getaddrinfo: ret[0], SrcAddress:<127.0.0.1|10000> ai_flags:[1], ai_family[2], ai_socktype[1], ai_protocol[6], ai_addrlen[16], ai_canonname[(null)] ParseSockAddr: ret[0], Address<127.0.0.1|10000> getaddrinfo: ret[0], SrcAddress:<192.168.137.129|10000> ai_flags:[1], ai_family[2], ai_socktype[1], ai_protocol[6], ai_addrlen[16], ai_canonname[(null)] ParseSockAddr: ret[0], Address<192.168.137.129|10000> getaddrinfo: ret[0], SrcAddress:<::|10000> ai_flags:[1], ai_family[10], ai_socktype[1], ai_protocol[6], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address<::|10000> getaddrinfo: ret[0], SrcAddress:<::0|10000> ai_flags:[1], ai_family[10], ai_socktype[1], ai_protocol[6], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address<::|10000> getaddrinfo: ret[0], SrcAddress:<::1|10000> ai_flags:[1], ai_family[10], ai_socktype[1], ai_protocol[6], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address<::1|10000> getaddrinfo: ret[0], SrcAddress:
ai_flags:[1], ai_family[10], ai_socktype[1], ai_protocol[6], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address
getaddrinfo: ret[0], SrcAddress:
ai_flags:[1], ai_family[10], ai_socktype[1], ai_protocol[6], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address
getaddrinfo: ret[0], SrcAddress:
ai_flags:[1], ai_family[10], ai_socktype[1], ai_protocol[6], ai_addrlen[28], ai_canonname[(null)] ParseSockAddr: ret[0], Address
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/220968.html原文链接:https://javaforall.net
