获取物理IP地址背后的诀窍是什么?

时间:2009-07-21 22:03:33

标签: c++ ip-address

当我使用C ++和winsock库转到“http://www.whatsmyip.org/”时,如何获得相同的IP地址?

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

我该如何做到这一点?

8 个答案:

答案 0 :(得分:15)

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

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

答案 1 :(得分:3)

你不能。

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

你想要完成什么?

答案 2 :(得分:1)

如果不使用网络之外的内容,则无法实现此目的。

返回的地址是您的计算机与外界之间的第一个公共IP地址。 10. ,192.168。,172。[16-31]。* ip地址为“私有”,不应完整转发到任何非私有IP地址。

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

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

如果您遇到特定问题,可能会有更好的答案。

答案 3 :(得分:1)

正如其他人所说,你需要网络上的第三方,例如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)

答案 4 :(得分:0)

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

答案 5 :(得分:0)

正如其他人所说,可能没有一个简单/好的解决方案。一个(尽管是hacky)解决方案可能是对'tracert'系统调用进行转换。例如:

tracert google.com

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

当然,这绝不是一个优雅的解决方案。但是,它可能会为您提供所需的信息。作为测试,您只需从命令行运行上述内容,看看它是否有用。

答案 6 :(得分:0)

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

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

我不知道如果我刚刚说的话有意义但是...我对服务器来说是全新的...就像我说这是出于学习目的。

再次感谢。 祝大家好运。

答案 7 :(得分:0)

enter image description here

获取外部IP的一种c / c ++方法是使用基于Web的IP地址API工具,将包含IP地址的网页下载到char数组中,并从HTML源中提取IP地址。这里有一些winsock代码来演示它。它使用http://api.ipify.org/的在线网络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;
}