通过 Socket Creation / getsockname 查找本地 IP

发布于 2024-09-05 07:30:11 字数 1502 浏览 2 评论 0原文

我需要在 C++ 中获取系统的 IP 地址。我遵循此处另一条评论的逻辑和建议,创建了一个套接字,然后利用 getsockname 来确定该套接字绑定到的 IP 地址。

但是,这似乎不起作用(下面的代码)。当我应该收到 128.etc 时,我却收到无效的 IP 地址(58.etc)

有什么想法吗?

   string Routes::systemIP(){

    // basic setup
    int sockfd;
    char str[INET_ADDRSTRLEN];
    sockaddr* sa;
    socklen_t* sl;
    struct addrinfo hints, *servinfo, *p;
    int rv;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;

    if ((rv = getaddrinfo("4.2.2.1", "80", &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return "1";
    }

    // loop through all the results and make a socket
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("talker: socket");
            continue;
        }

        break;
    }

    if (p == NULL) {
        fprintf(stderr, "talker: failed to bind socket\n");
        return "2";
    }

    // get information on the local IP from the socket we created
    getsockname(sockfd, sa, sl);

    // convert the sockaddr to a sockaddr_in via casting
    struct sockaddr_in *sa_ipv4 = (struct sockaddr_in *)sa;

    // get the IP from the sockaddr_in and print it
    inet_ntop(AF_INET, &(sa_ipv4->sin_addr.s_addr), str, INET_ADDRSTRLEN);
    printf("%s\n", str);

    // return the IP
    return str;
}

I need to get the IP address of a system within C++. I followed the logic and advice of another comment on here and created a socket and then utilized getsockname to determine the IP address which the socket is bound to.

However, this doesn't appear to work (code below). I'm receiving an invalid IP address (58.etc) when I should be receiving a 128.etc

Any ideas?

   string Routes::systemIP(){

    // basic setup
    int sockfd;
    char str[INET_ADDRSTRLEN];
    sockaddr* sa;
    socklen_t* sl;
    struct addrinfo hints, *servinfo, *p;
    int rv;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;

    if ((rv = getaddrinfo("4.2.2.1", "80", &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return "1";
    }

    // loop through all the results and make a socket
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("talker: socket");
            continue;
        }

        break;
    }

    if (p == NULL) {
        fprintf(stderr, "talker: failed to bind socket\n");
        return "2";
    }

    // get information on the local IP from the socket we created
    getsockname(sockfd, sa, sl);

    // convert the sockaddr to a sockaddr_in via casting
    struct sockaddr_in *sa_ipv4 = (struct sockaddr_in *)sa;

    // get the IP from the sockaddr_in and print it
    inet_ntop(AF_INET, &(sa_ipv4->sin_addr.s_addr), str, INET_ADDRSTRLEN);
    printf("%s\n", str);

    // return the IP
    return str;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

素食主义者 2024-09-12 07:30:11

您的代码已包含提示:无法绑定套接字。但是你删除了尝试连接的代码部分(你是从 Stevens UnP 复制的吗?)。该套接字尚未连接到任何东西,因此网络堆栈尚未为其分配本地地址。

连接套接字后,内核必须根据路由表为其选择本地地址。此时,getsockname(2) 将按预期工作。

Your code already contains the hint: failed to bind socket. But you cut the part of the code that attempts connecting out (did you copy from Stevens UnP?). The socket is not connected to anything, so the network stack has not assigned the local address to it yet.

Once you connect the socket the kernel has to select the local address for it according to the routing table. At that point getsockname(2) will work as expected.

孤独患者 2024-09-12 07:30:11

您不需要分配套接字来获取计算机的可用 IP 地址。您可以改用套接字 API gethostname() 和 gethostbyname() 函数。或者,在 Windows 上,您也可以使用 Win32 API GetAdaptersInfo() 或 GetAdaptersAddresses() 函数。

You do not need to allocate a socket to get the machine's available IP addresses. You can use the socket API gethostname() and gethostbyname() functions instead. Or, on Windows, you can alternatively use the Win32 API GetAdaptersInfo() or GetAdaptersAddresses() function instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文