【问题标题】:Whats the trick behind getting the physical IP address?获取物理 IP 地址背后的技巧是什么?
【发布时间】:2010-11-12 19:36:38
【问题描述】:

如何获得与使用 C++ 和 winsock 库访问“http://www.whatsmyip.org/”时相同的 IP 地址?

我知道如何获取“127.0.0.1”和路由器IP“192.168.1.103”... 但是当我到达“http://www.whatsmyip.org/”时,我得到了“65.55.105.132”......

我怎样才能做到这一点?

【问题讨论】:

标签: c++ ip-address


【解决方案1】:

一般来说 - 你不能。您可以打开到 whatmyip 的 http 连接并解析结果。或者正如 Justin 在 cmets 中建议的那样,使用 http://www.whatismyip.com/automation/n09230945.asp 并节省解析和带宽。但最后,这只会给你 NAT / 代理的 IP / 你和 whatsmyip 之间的任何东西。该地址仅通过转发连接到您的计算机。

没有通用的方法来检索路由器面向互联网的 IP 地址(即您看到的 65.55.105.132 IP。)即使可以,也没有理由不能有更多的 NAT 层进入路。

【讨论】:

  • +1,不知道你为什么被否决。你的答案是正确的。
  • whatismyip.com/automation/n09230945.asp 是一个更好的查询页面
  • @Eclipse whatismyip 实际上由于带宽原因更喜欢这种方式。这是双赢
【解决方案2】:

你不能。

http://www.whatsmyip.org 告诉你当你与它交谈时它看到的 IP 地址。它可能会看到您的、代理服务器、NAT 框或其他任何东西。你没办法知道。

你想完成什么?

【讨论】:

    【解决方案3】:

    嗯,真的没有什么技巧。 www.whatsmyip.com 可以告诉您的“外部”IP 地址的原因是因为他们收到了您的路由器已进行 NAT(网络地址转换)的请求,因此他们看到了您的公共 IP 地址。这是您无法在网络上的任意内部主机上真正获得的东西 - 除非您有 a server on the outside 可以查询或有一种机制来询问您的路由器它在发出公共互联网请求时使用的 IP 地址。

    【讨论】:

    • 而且在很多情况下,他的公共 IP 地址可能会随时发生变化。
    【解决方案4】:

    正如其他人所说,可能没有简单/出色的解决方案。一个(尽管很老套)的解决方案可能是使用“tracert”系统调用。例如:

    tracert google.com
    

    此调用将返回您的 PC 和 google.com(或任何外部站点)之间的所有路由器的列表。然后您可以遍历结果,获取不是 private IP address 范围的第一个节点。 (即不是 192.168.. 等)

    当然,这绝不是一个优雅的解决方案。但是,它可能会为您提供所需的信息。作为测试,您可以简单地从命令行运行以上代码,看看是否有帮助。

    【讨论】:

    • @Eric Pi:这种情况多久会改变一次?
    • @John:整个 tracert 路由的某些部分可能会经常更改。 (取决于碰巧处理给定数据包的路由器/服务器。)但是,最早的几跳应该相当稳定——仅当用户更改其内部网络/路由器设置时才会更改。
    • @如果他要将这些知识融入到程序中,那么当内部网络/路由器设置发生变化时,他的程序就会中断,除非他的“网络人”想告诉开发人员他们'将对网络进行无害的更改。
    【解决方案5】:

    如果不使用网络之外的东西,就无法做到这一点。

    返回的地址是你的电脑与外界之间的第一个公网IP地址。 10., 192.168., 172.[16-31].* IP 地址是“私有的”,不应原封不动地转发到任何非私有 IP 地址。

    在某些时候,私有 IP 地址必须链接到公共 IP 地址。从您的计算机到 whatsmyip.com 站点的路径中的第一个公共 IP 地址就是该页面上显示的内容。诀窍是您的计算机可能有一个公共 ip,或者可能有一些跃点到具有私有 ip 的计算机/交换机/路由器,直到最终有一个公共 ip。无法知道该跳数是多少,并且根据网络,路由可能会从一个请求更改为另一个请求,并且每次可能会有不同的跳数(对于家庭网络不太可能,但更有可能在公司网络)。

    获得第一个公共 IP 地址的唯一方法是将数据包发送到公共地址,并跟踪它所采用的路由。再次......该路线可以(并且确实)在复杂的网络上发生变化。

    如果您有一个特定的问题想要解决,可能会有更好的答案。

    【讨论】:

      【解决方案6】:

      正如其他人所说,您需要网络上的第三方(例如 whatismyip.com)来告诉您您的 IP 地址。我只是想补充一下,您不应该依赖 whatismyip.com,而是应该考虑设置自己的服务,因为这样的服务往往会来来去去或改变可能连接到它们的人(请参阅 this example 了解为什么会这样发生)。

      您可以轻松地为您的应用免费设置一项服务,例如基于 Google AppEngine。必要的请求处理程序可能类似于:

      from google.appengine.ext import webapp
      
      class RemoteAddressHandler(webapp.RequestHandler):
          def get(self):
              self.response.out.write(self.request.remote_addr)
      

      【讨论】:

      • 再说一次,这很可能不是一个永久地址,即使他可以通过入站连接到达。
      【解决方案7】:

      哇,这是一个非常快速的回复。谢谢大家的回答,现在我知道了。

      我目前正在构建一个 C++ HTTP 服务器用于学习目的。当我到达“whatismyip.org”时,我完成了将获得的 IP 地址转发到我的私人 ip“192.168.1.3”,以便我的服务器处理任何外部调用。我几乎创建了一个简单的 C++ 服务器。但是,我正在使用称为 No-IP DUC 的东西将“yellowyackets.no-ip.org”翻译成我的公共 IP,这样人们就不必记住我的公共 IP。但是由于 IP 发生变化,我必须跟踪我的新 IP 是什么,以便人们可以继续与我联系……所以我必须去“whatsmyip.org”了解我的新 IP。然后我想创建一个程序,它实际上会告诉我那是我的新 IP。

      我不知道我刚才所说的是否有道理,但是...我对服务器是全新的...就像我说的那样,这是为了学习目的。

      再次感谢。 祝大家好运。

      【讨论】:

        【解决方案8】:

        获取外部 ip 的一种 c/c++ 方法是使用基于 Web 的 IP 地址 API 工具,将包含您的 IP 地址的网页下载到一个字符数组中,然后从 HTML 源中提取 IP 地址。这是一些演示它的winsock代码。它使用 http://api.ipify.org/ 的在线 web api。

        //
        // Winsock get external ip address from website api at   api.ipify.org
        // api.ipify.org
        //
        
        #include <string.h>
        #include <stdio.h>
        
        #include <winsock2.h>
        #include <windows.h>
        #include <iostream>
        #include <vector>
        
        #include <algorithm>
        #include <cctype>
        #include <locale>
        #include <fstream>
        #include <ctime>
        #include <cstdlib>
        
        using namespace std;
        #pragma comment(lib,"ws2_32.lib")
        
        
        string website_HTML;
        locale local;
        char ipaddress[16];
        int ic=0;
        void get_Website(char *url );
        char mystring[] = " ";
        char seps[]   = " ,\t\n";
        char *token;
        char lineBuffer[200][80] ={' '};
        char buffer[10000];
        char ip_address[16];
        int i = 0, bufLen=0, j=0,lineCount=0;
        int lineIndex=0, posIndex=0;
        
        
        int main( void ){
        
            SYSTEMTIME st;
            GetLocalTime(&st);
            char *today = new char[32];
            memset(today,' ', sizeof(today) );
            sprintf(today,"%d-%d-%d", st.wYear , st.wMonth , st.wDay);
            memset(buffer,'\0',sizeof(buffer));
        
            get_Website("api.ipify.org" );
            for (size_t i=0; i<website_HTML.length(); ++i) website_HTML[i]= tolower(website_HTML[i],local);
        
            token = strtok( buffer , seps );  
            while( token != NULL ){
        
              strcpy(lineBuffer[lineIndex],token);
              int dot=0;
              for (int ii=0; ii< strlen( lineBuffer[lineIndex] ); ii++ ){
        
                  if (lineBuffer[lineIndex][ii] == '.') dot++;
                  if (dot>=3){
                      dot=0;
                      strcpy(ip_address,lineBuffer[lineIndex]);
                  }
              }
        
              token = strtok( NULL, seps );       
              lineIndex++;
           }
             cout<<"Your IP Address is  "<< ip_address<<" \n\n";
        
         return 0;
        }
        
        
        void get_Website(char *url ){
            WSADATA wsaData;
            SOCKET Socket;
            SOCKADDR_IN SockAddr;
            int lineCount=0;
            int rowCount=0;
            struct hostent *host;
            char *get_http= new char[256];
        
            memset(get_http,' ', sizeof(get_http) );
            strcpy(get_http,"GET / HTTP/1.1\r\nHost: ");
            strcat(get_http,url);
            strcat(get_http,"\r\nConnection: close\r\n\r\n");
        
            if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0){
                cout << "WSAStartup failed.\n";
                system("pause");
                //return 1;
            }
        
            Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
            host = gethostbyname(url);
        
            SockAddr.sin_port=htons(80);
            SockAddr.sin_family=AF_INET;
            SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
        
            if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0){
                cout << "Could not connect";
                system("pause");
                //return 1;
            }
            send(Socket,get_http, strlen(get_http),0 );
        
            int nDataLength;
            while ((nDataLength = recv(Socket,buffer,10000,0)) > 0){        
                int i = 0;
                while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r'){
        
                    website_HTML+=buffer[i];
                    i += 1;
                }               
            }
        
            closesocket(Socket);
            WSACleanup();
            delete[] get_http;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-30
          • 1970-01-01
          • 2015-06-25
          • 2012-03-12
          • 2011-09-08
          • 2011-06-04
          相关资源
          最近更新 更多