开发者

Finding Local IP via Socket Creation / getsockname

开发者 https://www.devze.com 2023-01-03 17:37 出处:网络
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

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 addr开发者_如何学Cinfo 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;
}


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消