Какая хитрость стоит за получением физического IP-адреса? - PullRequest
1 голос
/ 22 июля 2009

Как я могу получить тот же IP-адрес, который получаю, когда перехожу на "http://www.whatsmyip.org/" с использованием C ++ и библиотеки winsock?

Я знаю, как получить "127.0.0.1" и IP-адрес маршрутизатора "192.168.1.103" ... Но когда я получил "http://www.whatsmyip.org/", я получил" 65.55.105.132 "...

Как мне это сделать?

Ответы [ 8 ]

15 голосов
/ 22 июля 2009

В общем, вы не можете. Вы можете открыть http-соединение с whatmyip и проанализировать результат. Или, как предлагает Джастин в комментариях, используйте http://www.whatismyip.com/automation/n09230945.asp и экономьте на разборе и пропускной способности. Но, в конце концов, это даст вам только IP-адрес NAT / прокси / что угодно, что находится между вами и whatsmyip. Этот адрес только подключен к вашему компьютеру через пересылку.

Не существует общего способа получить IP-адрес вашего маршрутизатора в Интернете (это IP-адрес 65.55.105.132, который вы видите.) Даже если бы вы могли, нет никаких причин, по которым не может быть больше уровней доступа к NAT. путь.

3 голосов
/ 22 июля 2009

Вы не можете.

http://www.whatsmyip.org сообщает вам IP-адрес, который он видит, когда вы говорите с ним. Это может быть ваш, или прокси-сервер, или окно NAT, или что-то еще. У тебя нет возможности узнать.

Чего вы пытаетесь достичь?

1 голос
/ 22 июля 2009

Как уже говорили другие, вам нужен третий участник в сети, например whatismyip.com, чтобы сообщить вам ваш IP-адрес. Я просто хотел добавить, вы не должны зависеть от whatismyip.com, вместо этого вы должны подумать о создании своих собственных, так как подобные сервисы имеют тенденцию приходить и уходить или менять тех, кто может к ним подключиться (см. этот пример почему это может произойти).

Вы можете легко настроить службу, чтобы сделать это только для вашего приложения бесплатно, скажем, на основе Google AppEngine. Требуемый обработчик запроса может выглядеть примерно так:

from google.appengine.ext import webapp

class RemoteAddressHandler(webapp.RequestHandler):
    def get(self):
        self.response.out.write(self.request.remote_addr)
1 голос
/ 22 июля 2009

Нет способа сделать это без использования чего-то, что находится за пределами вашей сети.

Возвращенный адрес является первым публичным IP-адресом между вашим компьютером и внешним миром. 10. , 192.168. , 172. [16-31]. * Ip-адрес является «частным» и не должен пересылаться без изменений на любой не-частный ip-адрес.

В какой-то момент частные IP-адреса должны быть связаны с публичным IP-адресом. Первый публичный IP-адрес в пути от вашего компьютера до сайта whatsmyip.com - это то, что отображается на этой странице. Хитрость заключается в том, что ваш компьютер может иметь общедоступный IP-адрес или может быть некоторое количество переходов на компьютеры / коммутаторы / маршрутизаторы с частными IP-адресами, пока в конечном итоге не появится общедоступный IP-адрес. Нет никакого способа узнать, каково это количество прыжков, и в зависимости от сети маршрут может меняться от одного запроса к другому, и каждый раз может происходить различное количество прыжков (маловероятно для домашней сети, но более вероятно в корпоративная сеть).

Единственный способ получить первый общедоступный IP-адрес - это отправить пакет на общедоступный адрес и отследить выбранный маршрут. Опять же ... этот маршрут может (и может) измениться в сложной сети.

Если у вас есть конкретная проблема, которую вы пытаетесь решить, возможно, будет лучший ответ.

0 голосов
/ 01 ноября 2015

enter image description here

Один из способов получения внешнего ip на языке c / c ++ - использовать API-интерфейс для веб-адреса, загрузить веб-страницу, содержащую ваш IP-адрес, в массив char и извлечь IP-адрес из источника HTML. Вот некоторый код 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;
}
0 голосов
/ 22 июля 2009

Ого, это был очень быстрый ответ. Спасибо, ребята, за ответы, теперь я знаю лучше.

В настоящее время я создаю HTTP-сервер C ++ для целей обучения. Я выполнил переадресацию IP-адреса, который получаю, когда попал на «whatismyip.org», на свой частный ip «192.168.1.3», выполняя любой внешний вызов для обработки моим сервером. Так что в значительной степени я создал простой сервер C ++. Однако я использую что-то под названием No-IP DUC для перевода «yellowyackets.no-ip.org» на мой публичный IP, чтобы людям не приходилось запоминать мой публичный IP. Но поскольку IP-адреса меняются, я должен следить за тем, что является моим новым IP-адресом, чтобы люди могли продолжать подключаться ко мне ... поэтому мне нужно перейти на "whatsmyip.org", чтобы узнать мой новый IP-адрес. Затем я захотел создать программу, которая фактически сообщала бы мне, что это мой новый IP-адрес.

Я не знаю, имеет ли смысл то, что я только что сказал, но ... я новичок в серверах ... Как я уже сказал, это для целей обучения.

Еще раз спасибо. и удачи всем.

0 голосов
/ 22 июля 2009

Как уже говорили другие, не может быть легкого / отличного решения. (Хотя и хакерское) решение может заключаться в оболочке системного вызова 'tracert'. Пример:

tracert google.com

Этот вызов вернет список всех маршрутизаторов между вашим ПК и google.com (или любым внешним сайтом). Затем вы можете выполнить итерацию результатов, выбрав первый узел, который не является частным IP-адресом. диапазон. (То есть не 192.168. . и т. Д.)

Конечно, это ни в коем случае не элегантное решение. Тем не менее, он может дать вам необходимую информацию. В качестве теста вы можете просто запустить вышеизложенное из командной строки и посмотреть, полезно ли это.

0 голосов
/ 22 июля 2009

Ну, на самом деле, хитрости нет. Причина, по которой www.whatsmyip.com может определить ваш «внешний» IP-адрес, заключается в том, что они получают запрос, который был преобразован NAT (преобразован в сетевой адрес) вашим маршрутизатором, и поэтому видят ваш общедоступный IP-адрес. Это то, что вы не можете получить на произвольном внутреннем хосте в вашей сети - если только у вас нет сервера на внешней стороне , к которому вы могли бы обратиться или у которого есть механизм, чтобы спросить ваш маршрутизатор, какой IP-адрес у него используется при публичных интернет-запросах ..

...