首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在WINAPI中表示来自addrinfo的IP?

如何在WINAPI中表示来自addrinfo的IP?
EN

Stack Overflow用户
提问于 2022-10-25 23:17:35
回答 1查看 66关注 0票数 0

如何在WINAPI中将服务器的ip打印为a.b.c.d

代码语言:javascript
复制
int main(int argc, char ** argv)
{
    if (argc < 3)
        return -1;
    WSADATA wsData;
    int result;
    struct addrinfo * client = NULL, *ptr = NULL, hints;
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    result = getaddrinfo(argv[1], argv[2], &hints, &ptr);
    if (result < 0 )
        return -1;

    printf("%s", inet_addr(ptr->ai_addr->sa_data));
}

这将导致执行时出现分段错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-26 00:52:57

inet_addr()以虚线IPv4格式将以空结尾的字符串转换为二进制32位数字表示形式。例如,该数字适合存储在sockaddr_in中。这和你想要的正好相反。

ptr->ai_addr->sa_data不是以空结尾的字符串,这就是inet_addr()崩溃的原因。

要将sockaddr_...结构中的IP地址(例如来自getaddrinfo()的输出)转换为其字符串表示形式,可以使用inet_ntop(),例如:

代码语言:javascript
复制
int main(int argc, char* argv[])
{
    if (argc < 3)
        return -1;

    WSADATA wsData;
    int result = WSAStartup(MAKEWORD(2,0), &wsData);
    if (result != 0)
        return -1;
    
    struct addrinfo hints, *addrs, *ptr;
    char ipStrBuf[50];
    
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    result = getaddrinfo(argv[1], argv[2], &hints, &addrs);
    if (result != 0) {
        WSACleanup();
        return -1;
    }

    for (ptr = addrs; ptr != NULL; ptr = ptr->ai_next) {
        switch (ptr->ai_addr->sa_family) {
            case AF_INET: {
                struct sockaddr_in *ip4 = (struct sockaddr_in *) ptr->ai_addr;
                printf("%s", inet_ntop(AF_INET, &(ip4->sin_addr), ipStrBuf, sizeof(ipStrBuf)));
                break;
            }
            
            case AFINET6: {
                struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *) ptr->ai_addr;
                printf("%s", inet_ntop(AF_INET6, &(ip6->sin6_addr), ipStrBuf, sizeof(ipStrBuf)));
                break;
            }
        }
    }

    freeaddrinfo(addrs);
    WSACleanup();

    return 0;
}

或者,您可以使用getnameinfo(),指定NI_NUMERICHOST标志,例如:

代码语言:javascript
复制
int main(int argc, char* argv[])
{
    if (argc < 3)
        return -1;

    WSADATA wsData;
    int result = WSAStartup(MAKEWORD(2,0), &wsData);
    if (result != 0)
        return -1;
    
    struct addrinfo hints, *addrs, *ptr;
    char ipStrBuf[50];
    
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    result = getaddrinfo(argv[1], argv[2], &hints, &addrs);
    if (result != 0) {
        WSACleanup();
        return -1;
    }

    for (ptr = addrs; ptr != NULL; ptr = ptr->ai_next) {
        result = getnameinfo(ptr->ai_addr, ptr->ai_addrlen, ipStrBuf, sizeof(ipStrBuf), NULL, 0, NI_NUMERICHOST);
        if (result == 0) {
            printf("%s", ipStrBuf);
        }
    }

    freeaddrinfo(addrs);
    WSACleanup();

    return 0;
}

或者,您可以使用WSAAddressToString(),例如:

代码语言:javascript
复制
int main(int argc, char* argv[])
{
    if (argc < 3)
        return -1;

    WSADATA wsData;
    int result = WSAStartup(MAKEWORD(2,0), &wsData);
    if (result != 0)
        return -1;
    
    struct addrinfo hints, *addrs, *ptr;
    char ipStrBuf[50];
    DWORD ipBufSize;
    
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    result = getaddrinfo(argv[1], argv[2], &hints, &addrs);
    if (result != 0) {
        WSACleanup();
        return -1;
    }

    for (ptr = addrs; ptr != NULL; ptr = ptr->ai_next) {
        ipBufSize = sizeof(ipStrBuf);
        result = WSAAddressToStringA(ptr->ai_addr, ptr->ai_addrlen, NULL, ipStrBuf, &ipBufSize);
        if (result == 0) {
            printf("%s", ipStrBuf);
        }
    }

    freeaddrinfo(addrs);
    WSACleanup();

    return 0;
}

或者,您可以使用RtlIpv4AddressToString()RtlIpv6AddressToString(),例如:

代码语言:javascript
复制
int main(int argc, char* argv[])
{
    if (argc < 3)
        return -1;

    WSADATA wsData;
    int result = WSAStartup(MAKEWORD(2,0), &wsData);
    if (result != 0)
        return -1;
    
    struct addrinfo hints, *addrs, *ptr;
    char ipStrBuf[50];
    
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    result = getaddrinfo(argv[1], argv[2], &hints, &addrs);
    if (result != 0) {
        WSACleanup();
        return -1;
    }

    for (ptr = addrs; ptr != NULL; ptr = ptr->ai_next) {
        switch (ptr->ai_addr->sa_family) {
            case AF_INET: {
                struct sockaddr_in *ip4 = (struct sockaddr_in *) ptr->ai_addr;
                printf("%s", RtlIpv4AddressToStringA(&(ip4->sin_addr), ipStrBuf));
                break;
            }
            
            case AFINET6: {
                struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *) ptr->ai_addr;
                printf("%s", RtlIpv6AddressToStringA(&(ip6->sin6_addr), ipStrBuf));
                break;
            }
        }
    }

    freeaddrinfo(addrs);
    WSACleanup();

    return 0;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74201094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档