如何在 C 中获取外部 IP 地址?

新手上路,请多包涵

我将如何在 C++ 中查找用户的外部 IP?我需要一种适用于任何系统的方法,而不仅仅是我的。此外,系统可能位于路由器后面,因此 NAT 将发挥作用,使检索外部 IP 变得更加困难。

理想情况下,我想在不使用任何第三方服务(如 whatsmyip)的情况下执行此操作。但是,我不确定这是否可能。如果我不使用 3rd 方服务,我必须通过路由器,如果禁用 ping,我猜这可能是不可能的(我可能是错的,不太确定)。

如果我要使用像 whatsmyip 这样的第 3 方服务,我该怎么做呢?是否有他们公开的 Web 服务?我看过这个链接: http ://automation.whatismyip.com/n09230945.asp 但它似乎没有工作。是否可以通过使用一些 HTTP 方法获取外部 IP 并检索它,或者我是否需要有效地抓取页面以从中获取 IP?

我仅限于使用 Windows API 来完成此操作(没有第 3 方 API)

原文由 spdcbr 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 634
1 个回答

理论上,您可以使用 Windows uPnP API 来执行此操作。您将首先使用 UPnPDeviceFinder 枚举 Internet 网关设备。然后你得到一个 IUPnPRemoteEndpointInfo 网关(好吧, 通常 只有一个,无论如何)并调用它的 GetStringValue ,传递一个包含 "RemoteAddress" 的字符串来获取它的远程地址(我 认为 这意味着它的外部地址,尽管我承认我并不完全确定)。哦,因为这是 COM,所以它必须是系统字符串,而不是普通字符串。

从外部提供商那里获取 IP 容易得多。在不使用任何 3 rd方库的情况下,它的代码如下所示:

 #include <windows.h>
#include <wininet.h>
#include <string>
#include <iostream>

std::string real_ip() {

    HINTERNET net = InternetOpen("IP retriever",
        INTERNET_OPEN_TYPE_PRECONFIG,
        NULL,
        NULL,
        0);

    HINTERNET conn = InternetOpenUrl(net,
                                     "http://myexternalip.com/raw",
                                      NULL,
                                      0,
                                      INTERNET_FLAG_RELOAD,
                                      0);

    char buffer[4096];
    DWORD read;

    InternetReadFile(conn, buffer, sizeof(buffer)/sizeof(buffer[0]), &read);
    InternetCloseHandle(net);

    return std::string(buffer, read);
}

int main() {
    std::cout << real_ip() << "\n";
}

编译:

 cl ip_addr.cpp wininet.lib

注意:如果您的机器配置为使用 IPv6,这可以(并且将)检索您的 IPv6 地址)。

原文由 Jerry Coffin 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题