问题
How can I get the same IP Address I get when I go to "http://www.whatsmyip.org/" using C++ and winsock library?
I know how to get the "127.0.0.1" and the router IP "192.168.1.103"... But when I got to "http://www.whatsmyip.org/" I get "65.55.105.132"...
How can I accomplish this?
回答1:
In a general way - you can't. You could open an http connection to whatmyip and parse the result. Or as Justin suggests in the comments, use http://www.whatismyip.com/automation/n09230945.asp and save on parsing and bandwidth. But in the end, that's only going to give you the IP of the NAT / proxy / whatever that's between you and whatsmyip. That address is only connected to your computer through forwarding.
There isn't a general way to retrieve your router's internet facing IP address (that's the 65.55.105.132 IP you are seeing.) Even if you could, there's no reason that there couldn't be more layers of NATing getting in the way.
回答2:
You can't.
http://www.whatsmyip.org is telling you the IP address it sees when you talk to it. It could be seeing yours, or a proxy server, or a NAT box, or anything else. There's no way for you to know.
What are you trying to accomplish?
回答3:
There is no way to accomplish this without using something that is outside of your network.
The address returned is the first public ip address between your computer and the outside world. 10., 192.168., 172.[16-31].* ip address are "private" and should not be forwarded intact to any non-private ip address.
At some point, private ip addresses must be linked to a public ip address. The first public ip address in the path from your computer to the whatsmyip.com site is what is displayed on that page. The trick is that your computer might have a public ip, or there might be some number of hops to computers/switches/routers that have private ip's until there is eventually a public ip. There is no way to know what that number of hops is, and depending on the network the route can change from one request to another and there migth be a different number of hops each time (unlikely for a home network, but more likely in a corporate network).
The only way to get the first public ip address is to send a packet to an address that is public, and trace the route that it took. Again...that route can (and does) change on a complex network.
If you have a specific problem that you are trying to solve, there might be a better answer.
回答4:
As others have said, you need a third party on the network such as whatismyip.com to tell you your IP address. I just wanted to add, you shouldn't depend on whatismyip.com, instead you should consider setting up your own, as services like this tend to come and go or change who may connect to them (see this example for why that may happen).
You can easily set up a service to do this just for your application for free, say, based on Google AppEngine. The requisite request handler might look something like:
from google.appengine.ext import webapp
class RemoteAddressHandler(webapp.RequestHandler):
def get(self):
self.response.out.write(self.request.remote_addr)
回答5:
As others have said, there may not be an easy / great solution. An (albeit hacky) solution might be to shell out to the 'tracert' system call. Ex:
tracert google.com
This call will return a list of all routers in between your PC and google.com (or whatever external site.) You can then iterate through the results, taking the first node that isn't a private IP address range. (I.e., not 192.168.., etc.)
Granted, this is by no means an elegant solution. However, it might give you the info you need. As a test, you can simply run the above from a command line and see if it's helpful.
回答6:
Well, there is no trick really. The reason www.whatsmyip.com can tell your "outside" IP address is because they receive a request that has been NATed (Network Address Translated) by your router and so they see your public IP address. That is something that you can't really get at an arbitrary internal host on your network - not unless you have a server on the outside that you could query or have a mechanism to ask your router what IP address it uses when making public internet requests..
回答7:
Wow that was a very quick reply. Thanks guys for the answers now I know better.
I am currently building a C++ HTTP server for learning purpose. I accomplish to forward the IP address I get when I got to "whatismyip.org" to my private ip "192.168.1.3" making any external call to be handle by my server. So pretty much I created a simple C++ server. However I am using something called No-IP DUC to translate "yellowyackets.no-ip.org" to my public IP so that people don't have to memorize my public IP. But because the IP changes I have to keep track to whats is my new IP so that people can keep connecting to me... so I have to go to "whatsmyip.org" to know my new IP. Then I wanted to create a program that would actually tell me thats my new IP.
I dunno if what I just said make sense but... I am brand new to servers... Like I said this is for learning purpose.
Thanks again. and good luck to everyone.
回答8:
One c/c++ way of getting the external ip is to use a web based IP address API tool, download the webpage containing your IP address into a char array and extract the IP address from the HTML source. Here is some winsock code to demonstrate it. it uses http://api.ipify.org/ 's online 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;
}
来源:https://stackoverflow.com/questions/1161998/whats-the-trick-behind-getting-the-physical-ip-address