getaddrinfo测试

对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

你可能感兴趣的:(C++,IPv6,c++)