如何在C ++中获取外部IP地址? [英] How to get the external IP address in C++?

查看:170
本文介绍了如何在C ++中获取外部IP地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



如果我要使用像whatsmyip这样的第三方服务,我该怎么办呢?是否有他们公开的Web服务?我看过这个链接:



这是winsock方式。它只是提取服务器发送的HTML代码中嵌入的IP地址。



此代码使用 http://api.ipify.org/



以下是两个不同的代码。一个用于VS2012-2015,使用 strcpy_s(),一个用于Visual C ++ 6.0,使用 strcpy(),因为VS2012 -2015抛出一条错误消息,提示您使用 strcpy_s()而不是 strcpy()



Visual Studio 2012-2015代码。

  #includestdafx.h
#include< string.h>
#include< winsock2.h>
#include< windows.h>
#include< iostream>
#include< vector>
#include< locale>
#include< sstream>
using namespace std;
#pragma comment(lib,ws2_32.lib)


string website_HTML;
locale local;
void get_Website(string url);
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){
cout<< \\\
\\\
\\\
;
get_Website(api.ipify.org);
for(size_t i = 0; i< website_HTML.length(); ++ i)website_HTML [i] = tolower(website_HTML [i],local);

istringstream ss(website_HTML);
string stoken;

while(getline(ss,stoken,'\ n')){

// cout<< - ><< stoken.c_str()<< \\\
;

strcpy_s(lineBuffer [lineIndex],stoken.c_str());
int dot = 0;
for(int ii = 0; ii< strlen(lineBuffer [lineIndex]); ii ++){

if(lineBuffer [lineIndex] [ii] =='。')dot ++;
if(dot> = 3){
dot = 0;
strcpy_s(ip_address,lineBuffer [lineIndex]);
}
}

lineIndex ++;
}
cout<< 你的IP地址是<< ip_address<< \ n \\ n;


cout<< \ n按任意键关闭。\ n \\ n;
cin.ignore(); cin.get();

返回0;
}

// *********************************** *****************

void get_Website(string url){
WSADATA wsaData;
SOCKET插座;
SOCKADDR_IN SockAddr;
int lineCount = 0;
int rowCount = 0;
struct hostent * host;
string get_http;


get_http =GET / HTTP / 1.1 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \
;

if(WSAStartup(MAKEWORD(2,2),& wsaData)!= 0){
cout<< WSAStartup failed.\;
system(暂停);
//返回1;
}

Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
host = gethostbyname(url.c_str());

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<< 无法连接;
system(暂停);
//返回1;
}
send(Socket,get_http.c_str(),strlen(get_http.c_str()),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();

}

Visual C ++ 6.0代码

  #include< string.h> 
#include< winsock2.h>
#include< windows.h>
#include< iostream>
#include< vector>
#include< locale>
#include< sstream>
using namespace std;
#pragma comment(lib,ws2_32.lib)


string website_HTML;
locale local;
void get_Website(string url);
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){
cout<< \\\
\\\
\\\
;
get_Website(api.ipify.org);
for(size_t i = 0; i< website_HTML.length(); ++ i)website_HTML [i] = tolower(website_HTML [i],local);

istringstream ss(website_HTML);
string stoken;

while(getline(ss,stoken,'\ n')){

strcpy(lineBuffer [lineIndex],stoken.c_str());
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]);
}
}
lineIndex ++;
}
cout<<你的IP地址是<< ip_address<<\ n\ n;

cout<<\ n按任意键关闭。\ nn。
cin.ignore(); cin.get();


返回0;
}

// *********************************** *****************

void get_Website(string url){
WSADATA wsaData;
SOCKET插座;
SOCKADDR_IN SockAddr;
int lineCount = 0;
int rowCount = 0;
struct hostent * host;
string get_http;


get_http =GET / HTTP / 1.1 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \
;

if(WSAStartup(MAKEWORD(2,2),& wsaData)!= 0){
cout<< WSAStartup failed.\;
system(暂停);
//返回1;
}

Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
host = gethostbyname(url.c_str());

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<< 无法连接;
system(暂停);
//返回1;
}
send(Socket,get_http.c_str(),strlen(get_http.c_str()),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 + =缓冲液[I];
i + = 1;
}
}

closesocket(Socket);
WSACleanup();

}


How would I go about finding the external IP of a user in C++? I need a method that would work for any system, not just mine. Additionally, the system could be behind a router, thus NAT would come into play making it harder to retrieve the external IP.

Ideally, I'd like to do this without using any 3rd party service like whatsmyip. However, I'm not sure if this is possible. If I don't use a 3rd party service, I'd have to go through the router and if ping is disabled I'm guessing this might not be possible (I could be wrong, not too sure).

If I were to use a 3rd party service like whatsmyip, how might I go about this? Is there a web service that they expose? I've seen this link: http://automation.whatismyip.com/n09230945.asp but it doesn't seem to be working. Would it be possible to fetch the external IP by using some HTTP methods and retrieve it, or would I effectively need to scrape the page to get the IP from it?

I'm limited to using Windows API's to accomplish this (no 3rd party API's)

解决方案

Here is the winsock way. It simply extracts the IP address embedded in the HTML code that the server sent.

This code uses http://api.ipify.org/ .

Below are two different codes. One for VS2012-2015 that uses strcpy_s( ) and one for Visual C++ 6.0 that uses strcpy( ) , because VS2012-2015 throws an error message prompting you to use strcpy_s( ) instead of strcpy( ).

Visual Studio 2012-2015 code.

#include "stdafx.h"
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <vector>
#include <locale>
#include <sstream>
using namespace std;
#pragma comment(lib,"ws2_32.lib")


string website_HTML;
locale local;
void get_Website(string url);
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){
    cout << "\n\n\n";
    get_Website("api.ipify.org");
    for (size_t i = 0; i<website_HTML.length(); ++i) website_HTML[i] = tolower(website_HTML[i], local);

    istringstream ss(website_HTML);
    string stoken;

    while (getline(ss, stoken, '\n')) {

        //cout <<"-->"<< stoken.c_str() << '\n';

        strcpy_s(lineBuffer[lineIndex], stoken.c_str());
        int dot = 0;
        for (int ii = 0; ii< strlen(lineBuffer[lineIndex]); ii++){

            if (lineBuffer[lineIndex][ii] == '.') dot++;
            if (dot >= 3){
                dot = 0;
                strcpy_s(ip_address, lineBuffer[lineIndex]);
            }
        }

        lineIndex++;
    }
    cout << "Your IP Address is  " << ip_address << " \n\n";


    cout << "\nPress ANY key to close.\n\n";
    cin.ignore(); cin.get();

    return 0;
}

//****************************************************

void get_Website(string url){
    WSADATA wsaData;
    SOCKET Socket;
    SOCKADDR_IN SockAddr;
    int lineCount = 0;
    int rowCount = 0;
    struct hostent *host;
    string get_http;


    get_http = "GET / HTTP/1.1\r\nHost: " + url + "\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.c_str());

    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.c_str(), strlen(get_http.c_str()), 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();

}

Visual C++ 6.0 code

    #include <string.h>
    #include <winsock2.h>
    #include <windows.h>
    #include <iostream>
    #include <vector>
    #include <locale>
    #include <sstream>
    using namespace std;
    #pragma comment(lib,"ws2_32.lib")


    string website_HTML;
    locale local;
    void get_Website(string url );
    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 ){
        cout << "\n\n\n";
        get_Website("api.ipify.org" );
        for (size_t i=0; i<website_HTML.length(); ++i) website_HTML[i]= tolower(website_HTML[i],local);

        istringstream ss(website_HTML);
        string stoken;

        while(getline(ss, stoken, '\n')) {

                  strcpy(lineBuffer[lineIndex],stoken.c_str());
                  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]);
                      }
                  }
                  lineIndex++;
         }
        cout<<"Your IP Address is  "<< ip_address<<" \n\n"; 

       cout<<"\nPress ANY key to close.\n\n";
       cin.ignore(); cin.get(); 


     return 0;
}

 //****************************************************

void get_Website(string url ){
    WSADATA wsaData;
    SOCKET Socket;
    SOCKADDR_IN SockAddr;
    int lineCount=0;
    int rowCount=0;
    struct hostent *host;
    string get_http;


    get_http = "GET / HTTP/1.1\r\nHost: " + url + "\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.c_str());

    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.c_str(), strlen(get_http.c_str()),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();

}

这篇关于如何在C ++中获取外部IP地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆