如何以编程方式获取互联网IP地址?
1)如果计算机使用USB调制解调器直接连接到互联网。
2)如果计算机通过另一台计算机或调制解调器/路由器连接到互联网。
是否有办法同时完成这两个任务?
附注:此链接提供了确切的互联网IP地址,但我该如何在程序中使用它?
1)如果计算机使用USB调制解调器直接连接到互联网。
2)如果计算机通过另一台计算机或调制解调器/路由器连接到互联网。
是否有办法同时完成这两个任务?
附注:此链接提供了确切的互联网IP地址,但我该如何在程序中使用它?
你可以编写套接字代码,向该链接发送http请求。
在Unix/Linux/Cygwin下,您可以使用system("wget http://www.whatismyip.com/automation/n09230945.asp");然后打开文件“n09230945.asp”并读取其内容。
以下是使用套接字进行请求的示例(我修改了一个在线示例以用于此特定目的)。注意:这只是一个示例,真正的实现需要更好地处理错误:
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define RCVBUFSIZE 1024
int main(int argc, char *argv[])
{
int sock; // Socket descriptor
struct sockaddr_in servAddr; // server address
unsigned short servPort; // server port
char const *servIP; // Server IP address (dotted quad)
char const *request; // String to send to server
char recvBuffer[RCVBUFSIZE]; // Buffer for response string
unsigned int requestLen; // Length of string to send
int bytesRcvd; // Bytes read in single recv()
bool status = true;
// Initialize port
servIP = "72.233.89.199";
servPort = 80;
request = "GET /automation/n09230945.asp HTTP/1.1\r\nHost: www.whatismyip.com\r\n\r\n";
std::cout << request << std::endl;
/* Create a reliable, stream socket using TCP */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
status = false;
}
if (status)
{
// Convert dotted decimal into binary server address.
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(servIP);
servAddr.sin_port = htons(servPort);
// Connect to the server.
if (connect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
{
status = false;
}
}
if (status)
{
// Calculate request length.
requestLen = strlen(request);
// Send the request to the server.
if (send(sock, request, requestLen, 0) != requestLen)
{
status = false;
}
}
if (status)
{
std::cout << "My IP Address: ";
if ((bytesRcvd = recv(sock, recvBuffer, RCVBUFSIZE - 1, 0)) <= 0)
{
status = false;
}
if (status && (bytesRcvd >0) && (bytesRcvd < (RCVBUFSIZE-1)))
{
recvBuffer[bytesRcvd] = '\0';
std::cout << recvBuffer << std::endl;
}
}
close(sock);
return 0;
}
gethostbyname()
系列函数(请参见man gethostbyname
)和inet_ntoa
。 gethostbyname()
查询DNS并返回主机名的IP地址列表,您可以使用inet_ntoa
打印它们。#include <stdio.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char** argv)
{
struct hostent* host = gethostbyname(argv[1]);
int count = 0;
char** current_addr = host->h_addr_list;
while (*current_addr != NULL)
{
struct in_addr* addr = (struct in_addr*)(*current_addr);
printf("address[%d]: %s\n", count, inet_ntoa(*addr));
++current_addr;
++count;
}
}
来自我的Kubuntu 10.04机器的一个例子:
mcc@fatback:~/sandbox/c$ ./gethostbyaddr_ex www.yahoo.com
address[0]: 69.147.125.65
address[1]: 67.195.160.76
实现 url.h 请求你提供的链接 http://www.gnutelephony.org/doxy/bayonne2/a00242.html 不应该太难。我记得曾经用过一个叫做 URLStream.h 的 wget C++ 包装器,它使用了提取运算符,这使得这个任务变得非常容易,但我似乎找不到它了。
根据您编写的程序需要运行的上下文,您可能希望通过DBus询问NetworkManager来解决此问题(请参见http://projects.gnome.org/NetworkManager/developers/)
这仅适用于桌面系统(甚至不是所有桌面系统...但大多数发行版现在使用NM)
此外,这对于#2没有帮助,但是您可以使用STUN服务器请参阅维基百科