Linux / C ++:获取Internet IP地址(不是本地计算机的IP)

时间:2010-06-14 15:09:50

标签: c++ linux networking ip-address

如何以编程方式获取Internet IP地址?

1)如果计算机使用USB调制解调器直接连接到Internet。

2)如果计算机通过另一台计算机或调制解调器/路由器连接到互联网。

我有办法做到这两点吗?

P.S。 This link完全提供了Internet IP,但我如何在我的程序中使用它?

7 个答案:

答案 0 :(得分:4)

您需要与外部服务器通信。向http://checkip.dyndns.orghttp://www.whatismyip.com等网站发出HTTP请求即可。

要执行HTTP请求,您可以使用libcurl

答案 1 :(得分:3)

如果您想通过c ++访问网页,请转到CurlPP。用它来下载你已经找到的whatismyip-page,你已经完成了。

答案 2 :(得分:2)

  1. 您可以编写套接字代码以向该链接发送http请求。

  2. 在unix / linux / cygwin下你可以使用system(“wget http://www.whatismyip.com/automation/n09230945.asp”);然后打开文件“n09230945.asp”并阅读其内容。

  3. 以下是如何使用套接字发出请求的示例(我为此特定目的修改了一个在线示例)。注意:这是一个示例,真正的实现需要更好地处理错误:

    #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;
    }
    

答案 3 :(得分:2)

对于C / C ++,您正在寻找gethostbyname()系列中的函数(请参阅man gethostbyname)和inet_ntoagethostbyname()查询DNS并返回主机名的IP地址列表,然后可以使用inet_ntoa打印。

这是一个示例程序,它将查找指定主机名的IP地址并将其打印出来。注意:我没有进行任何错误检查,所以要小心!

#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

答案 4 :(得分:0)

一般来说,没有正确的答案。计算机可能没有Internet IP地址,可以有一个,但也可以有多个外部IP。如果它有一个,你仍然无法在本地获得它,只能通过联系外部服务,它会告诉你你从哪里连接。您的链接就是这样的服务示例。

答案 5 :(得分:0)

实现url.h以请求您提供的链接http://www.gnutelephony.org/doxy/bayonne2/a00242.html应该不会太困难。我记得曾经使用一个名为URLStream.h的wget的C ++包装器,它使用了提取操作符,这使得这个任务变得非常容易,但我似乎无法找到它。

答案 6 :(得分:0)

根据您编写的程序需要运行的上下文,您可能希望通过询问NetworkManager而不是DBus来解决此问题(请参阅http://projects.gnome.org/NetworkManager/developers/

这实际上只适用于桌面系统(甚至不是所有这些系统......但大多数发行版现在使用NM)

这对#2没有帮助,但是你可以使用STUN服务器see Wikipedia