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

发布于 2024-09-05 05:19:18 字数 266 浏览 7 评论 0原文

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

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

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

我有办法两全其美吗?

PS 此链接准确地给出了互联网IP,但我如何在我的程序中使用它?

How can I programmatically get the Internet IP address?

1) If the computer is directly connected to the Internet using a USB modem.

2) If the computer is connected to the internet via another computer or a modem/router.

I there a way to do both?

P.S. This link gives exactly the Internet IP, but how can I use it in my program?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

简美 2024-09-12 05:19:18

您需要与外部服务器通信。向 http://checkip.dyndns.orghttp://www.whatismyip.com 就可以了。

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

You need to talk to an external server. Issuing HTTP requests to sites like http://checkip.dyndns.org or http://www.whatismyip.com will do the trick.

To do the HTTP request, you can for example use libcurl.

一百个冬季 2024-09-12 05:19:18

如果您想通过 C++ 访问网页,请使用 CurlPP。使用它下载您已经找到的whatismyip-page,然后就完成了。

If you want to access a web page via c++, go for CurlPP. Use it to download the whatismyip-page you already found and you're done.

停顿的约定 2024-09-12 05:19:18
  1. 您可以编写套接字代码来向该链接发送 http 请求。

  2. 在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;
}
  1. You can write socket code to send an http request to that link.

  2. Under unix/linux/cygwin you can use system("wget http://www.whatismyip.com/automation/n09230945.asp"); then open the file "n09230945.asp" and read its contents.

Here is an example of how to make the request using sockets (I modified an online example for this specific purpose). NOTE: It is an example and a real implementation would need to handle the errors better:

#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;
}
述情 2024-09-12 05:19:18

对于 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

For C/C++, you're looking for functions in the gethostbyname() family (see man gethostbyname) and inet_ntoa. The gethostbyname() query DNS and return a list of IP addresses for the host name, which you could then print with inet_ntoa.

Here's an example program that will lookup the IP addresses of the specified host name and print them out. Note: I've not put in any error checking, so be careful!

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

An example from my Kubuntu 10.04 machine:

mcc@fatback:~/sandbox/c$ ./gethostbyaddr_ex www.yahoo.com
address[0]: 69.147.125.65
address[1]: 67.195.160.76
千紇 2024-09-12 05:19:18

一般来说,没有正确答案。一台计算机可能没有 Internet IP 地址,也可以有一个,但也可以有多个外部 IP。对于有的情况,您仍然无法在本地获取它,只能通过联系外部服务,该服务会告诉您从哪里连接。您的链接是此类服务的一个示例。

Generally speaking, there is no correct answer. A computer might have no Internet IP adddress, can have one, but can also have multiple external IPs. For the case when it has one, you still can't get it locally, only by contacting an external service, which will tell you where you've connected from. Your link is an example of a service like that.

怕倦 2024-09-12 05:19:18

实现 url.h 来请求您提供的链接应该不会太困难 http: //www.gnutelephony.org/doxy/bayonne2/a00242.html。我记得有一次为 wget 使用了一个名为 URLStream.h 的 C++ 包装器,它使用了提取运算符,这将使这项任务变得非常简单,但我似乎找不到它。

It shouldn't be too difficult to implement url.h to request the link you gave http://www.gnutelephony.org/doxy/bayonne2/a00242.html. I remember once using a C++ wrapper for wget called URLStream.h that used the extraction operator which would make this task really easy but I can't seem to find it.

残疾 2024-09-12 05:19:18

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

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

这也并不适用对#2没有帮助,但是你可以使用STUN服务器参见维基百科

Depending on the context in which the program you are writing needs to run you might want to solve this by asking NetworkManager over DBus (see http://projects.gnome.org/NetworkManager/developers/)

This really only applies to desktop systems (and not even all of them... but most distros use NM now)

Also this doesn't help with #2, however you could use a STUN server see Wikipedia

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文