利用IP地址得到物理位置:
原理:這裏要講的就是通過socket去發送GET請求,發送至轉換的網站,然後解析其中的內容,這裏GET的是http://ip.chinaz.com/網站。
步驟:
- 先使用Wireshark抓包工具,抓取查詢http://ip.chinaz.com/的封包,然後就可以模仿這個封包,利用socket發送GET請求,獲取IP地址的物理地址信息了。
從上面可以得到要發送的封包的具體格式:
GET /?IP=223.124.1.232 HTTP/1.1\r\n
Host: ip.chinaz.com\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n
Accept-Language: zh-CN,zh;q=0.8\r\n\r\n
使用socket進行send發送時,緩衝區填入上面的固定格式即可,這裏要改的只有?IP=你要查詢的IP地址
這裏還要強調一點,在上面的封包中最好不要加上Accept-Encoding: gzip, deflate, sdch\r\n,除非你會使用代碼解壓gzip壓縮包,否則recv接收服務器響應回來的文檔的時候,發送的是gzip壓縮過的數據。由於我們只是查詢而已,所以去掉這個字段,讓服務器直接發回來html文檔,然後我們解析就可以了。
下面是一個解析http://ip.chinaz.com/獲取物理地址的例子:
//名字轉IP(OK,New)
char* NET::GetIp(char* szhostname)
{
char* szip = NULL;
char* ipbit = NULL;
hostent* ipstr = NULL;
szip = new char[30];
if (!szip)
goto Err;
ZeroMemory(szip, 30);
ipstr = gethostbyname(szhostname);
if (ipstr == NULL)
goto Err;
ipbit = inet_ntoa(*(in_addr*)ipstr->h_addr);
if (ipbit == NULL)
goto Err;
memcpy(szip, ipbit, strlen(ipbit));
return szip;
Err:
return NULL;
}
//連接HTTP服務器(OK,Connected)
SOCKET NET::ConnectHttpServer(char* szip)
{
SOCKET szclient_socket = 0;
szclient_socket = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == szclient_socket)
goto Err;
//連接服務器
SOCKADDR_IN info;
info.sin_port = htons(80);
info.sin_family = AF_INET;
info.sin_addr.S_un.S_addr = inet_addr(szip);
if (0 != connect(szclient_socket, (SOCKADDR*)&info, sizeof(SOCKADDR)))
goto Err;
//返回
return szclient_socket;
Err:
if (szclient_socket != NULL && szclient_socket != INVALID_SOCKET)
{
closesocket(szclient_socket);
szclient_socket = 0;
}
return 0;
}
//設置套接字緩衝區大小(OK)
BOOL NET::SetSocketInfo(SOCKET szsocket,int uBufferSize)
{
if (SOCKET_ERROR == setsockopt(szsocket, SOL_SOCKET, SO_RCVBUF, (char*)&uBufferSize, sizeof(int)))
goto Err;
if (SOCKET_ERROR == setsockopt(szsocket, SOL_SOCKET, SO_SNDBUF, (char*)&uBufferSize, sizeof(int)))
goto Err;
return TRUE;
Err:
return FALSE;
}
//UTF8轉ANSI字符串(OK,New)
char* STR::Utf8ToAnsi(char* utf8,int len,char szcc)
{
BOOL szok = FALSE;
int szlen = 0;
char* szretstr = NULL;
wchar_t* whar_str = NULL;
//UTF8轉UNICODE
szlen = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0);
if (szlen <= 0)
goto Err;
szlen += 1;
whar_str = new wchar_t[szlen];
if (!whar_str)
goto Err;
ZeroMemory(whar_str, szlen * sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, utf8, len, whar_str, szlen);
if (GetLastError() != 0)
goto Err;
//UNICODE轉ANSI
szlen = WideCharToMultiByte(CP_ACP, 0, whar_str, len, NULL, 0,&szcc,&szok);
if (szlen <= 0)
goto Err;
szlen += 1;
szretstr = new char[szlen];
if (!szretstr)
goto Err;
ZeroMemory(szretstr, szlen * sizeof(char));
WideCharToMultiByte(CP_ACP, 0, whar_str, len, szretstr, szlen, &szcc, &szok);
if (GetLastError() != 0)
goto Err;
if (whar_str)
{
delete[] whar_str;
whar_str = NULL;
}
return szretstr;
Err:
if (whar_str)
{
delete[]whar_str;
whar_str = NULL;
}
return NULL;
}
//獲取物理地址(OK,ip.chinaz.com,New)
char* GET_POINT::GetPoint(char* ip_address,char* get_ip_de_host_name)
{
int szlen = 0;
char* szPoint = NULL;
char* szTemp = NULL;
char* szTemp2 = NULL;
char* szTemp3 = NULL;
char* get_host_name_ip = NULL;
SOCKET http_client_socket = NULL;
char packet[400] ="GET /";
strcat(packet, "?IP=");
strcat(packet, ip_address);
strcat(packet, " HTTP/1.1\r\n" \
"Host: "
);
strcat(packet, get_ip_de_host_name);
strcat(packet, "\r\n"
"Connection: keep-alive\r\n"
"Cache-Control: max-age=0\r\n"
"Upgrade-Insecure-Requests: 1\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
"Accept-Language: zh-CN,zh;q=0.8\r\n\r\n"
);
char* recv_buffer = NULL;
//代碼開始
recv_buffer = new char[50000];
if (!recv_buffer)
goto Err;
ZeroMemory(recv_buffer, 50000);
//返回解析物理地址的主機的IP地址
get_host_name_ip = NET::GetIp(get_ip_de_host_name);
if (get_host_name_ip == NULL)
goto Err;
//連接服務器
http_client_socket = NET::ConnectHttpServer(get_host_name_ip);
if (http_client_socket == 0)
goto Err;
//設置緩衝區大小
if (!NET::SetSocketInfo(http_client_socket, 30000))
goto Err;
if (send(http_client_socket, packet, strlen(packet), 0) <= 0)
goto Err;
if (recv(http_client_socket, recv_buffer, 50000, 0) <= 0)
goto Err;
szTemp3 = STR::Utf8ToAnsi(recv_buffer, -1,'.');
if (szTemp3 == NULL)
goto Err;
szTemp = StrStrA(szTemp3, "IP的物理位置");
if (szTemp == NULL)
goto Err;
szTemp = StrStrA(szTemp, "w50");
if (szTemp == NULL)
goto Err;
szTemp += strlen("w50-0\">"); //???
if (szTemp == NULL)
goto Err;
szTemp2 = strchr(szTemp, '<');
if (szTemp2 == NULL)
goto Err;
szlen = szTemp2 - szTemp;
if (szlen <= 0)
goto Err;
szlen += 1;
szPoint = new char[szlen];
if (!szPoint)
goto Err;
ZeroMemory(szPoint, szlen);
memcpy(szPoint, szTemp, szlen - 1);
if (get_host_name_ip)
{
delete[]get_host_name_ip;
get_host_name_ip = NULL;
}
if (http_client_socket)
{
closesocket(http_client_socket);
http_client_socket = 0;
}
if (recv_buffer)
{
delete[]recv_buffer;
recv_buffer = NULL;
}
if (szTemp3)
{
delete[]szTemp3;
szTemp3 = NULL;
}
return szPoint;
Err:
if (get_host_name_ip)
{
delete[]get_host_name_ip;
get_host_name_ip = NULL;
}
if (http_client_socket)
{
closesocket(http_client_socket);
http_client_socket = 0;
}
if (recv_buffer)
{
delete[]recv_buffer;
recv_buffer = NULL;
}
if (szTemp3)
{
delete[]szTemp3;
szTemp3 = NULL;
}
return NULL;
}