【问题标题】:Getting my own IP address by connect()ing using UDP socket?使用 UDP 套接字通过 connect()ing 获取我自己的 IP 地址?
【发布时间】:2014-09-16 22:16:55
【问题描述】:

我听说我可以通过创建UDP socket 并connect() 到Google 等有效的目标IP 地址来获得自己的IP 地址(不是127.0.0.1)。

但是,我找不到任何参考或示例。

这可能吗?如果是这样,我该怎么做?


char* get_my_ip() {
    int sockfd;
    struct sockaddr_storage remoteaddr; // client address
    socklen_t addrlen;
    char remoteIP[INET6_ADDRSTRLEN];
    char *ip_addr;
    ip_addr = malloc(sizeof(char) * INET6_ADDRSTRLEN);
    int rv;

    struct addrinfo hints, *ai, *p;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;
    if ((rv = getaddrinfo("8.8.8.8", "http", &hints, &ai)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        exit(1);
    }
    // loop through all the results and make a socket
    for(p = ai; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
            p->ai_protocol)) == -1) {
            perror("UDP: socket");
            continue;
        }

        if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("UDP: connect");
            continue;
        }
        break;
    }
    if (p == NULL) {
        fprintf(stderr, "UDP: failed to bind socket\n");
        exit(2);
    }

    getsockname(sockfd, (struct sockaddr*)&remoteaddr, &addrlen);

    // deal with both IPv4 and IPv6:
    if (remoteaddr.ss_family == AF_INET) {
        struct sockaddr_in *s = (struct sockaddr_in *)&remoteaddr;
        inet_ntop(AF_INET, &s->sin_addr, remoteIP, addrlen);
    }
    else { // AF_INET6
        struct sockaddr_in6 *s = (struct sockaddr_in6 *)&remoteaddr;
        inet_ntop(AF_INET6, &s->sin6_addr, remoteIP, addrlen);
    }
    printf("IP_ADDRESS:%s", remoteIP);

    freeaddrinfo(ai); // all done with this structure
    close(sockfd);

    strcpy(ip_addr, remoteIP);
    return ip_addr;
}

【问题讨论】:

  • 如果你从一个系统调用中得到-1,你必须立即调用perror(),而不是在调用另一个系统调用之后,例如在这种情况下的close()。跨度>

标签: c linux sockets network-programming udp


【解决方案1】:

调用connect(),然后在您的套接字上调用getsockname()。它将返回套接字现在绑定的 IP 地址,该地址已被 IP 路由表选择为到目标地址的最佳路由。

但这不一定是您要查找的 IP 地址,除非您只有一个外部 IP 地址。

如果您在调制解调器或路由器的另一端谈论您的 公共 IP 地址,则此技术根本不适用。

【讨论】:

  • 我写了一个函数get_my_ip(),并将函数代码附加到问题的末尾。虽然当我在 main() 中使用相同的代码时它可以工作,但当我将代码放到一个单独的函数中并在 main 中调用 get_my_ip 时,它会为我的 IP 打印一些奇怪的字符(�&^�T)。你知道我的程序缺少什么吗?谢谢。
猜你喜欢
  • 2013-04-01
  • 1970-01-01
  • 2021-11-14
  • 2021-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多