Linux / C ++: получить IP-адрес в Интернете (не IP-адрес локального компьютера) - PullRequest
2 голосов
/ 14 июня 2010

Как программно получить IP-адрес в Интернете?

1) Если компьютер напрямую подключен к Интернету с помощью USB-модема.

2) Если компьютер подключен кИнтернет через другой компьютер или модем / маршрутизатор.

Есть ли способ сделать и то и другое?

PS Эта ссылка дает именно IP-адрес Интернета, но как я могу использоватьэто в моей программе?

Ответы [ 7 ]

4 голосов
/ 14 июня 2010

Вам нужно поговорить с внешним сервером.Отправка HTTP-запросов на такие сайты, как http://checkip.dyndns.org или http://www.whatismyip.com, сделает свое дело.

Для выполнения HTTP-запроса вы можете, например, использовать libcurl .

3 голосов
/ 14 июня 2010

Если вы хотите получить доступ к веб-странице через c ++, выберите CurlPP . Используйте его для загрузки whatismyip-страницы , которую вы уже нашли, и все готово.

2 голосов
/ 14 июня 2010

Для C / C ++ вы ищете функции семейства gethostbyname() (см. man gethostbyname) и inet_ntoa. gethostbyname() запрашивает 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
2 голосов
/ 14 июня 2010
  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;
}
0 голосов
/ 16 июня 2010

В зависимости от контекста, в котором необходимо запустить программу, которую вы пишете, вы можете решить эту проблему, задав NetworkManager через DBus (см. http://projects.gnome.org/NetworkManager/developers/)

Это действительно только для настольных систем (и дажевсе они ... но большинство дистрибутивов используют NM сейчас)

Также это не поможет с №2, однако вы можете использовать сервер STUN , см. Википедию

0 голосов
/ 14 июня 2010

Не должно быть слишком сложно реализовать url.h для запроса ссылки, которую вы дали http://www.gnutelephony.org/doxy/bayonne2/a00242.html. Я помню, как однажды использовал оболочку C ++ для wget с именем URLStream.h, который использовал оператор извлечения, который выполнял бы эту задачудействительно легко, но я не могу его найти.

0 голосов
/ 14 июня 2010

Вообще говоря, нет правильного ответа.Компьютер может не иметь IP-адреса в Интернете, может иметь его, но также может иметь несколько внешних IP-адресов.Для случая, когда он есть, вы все равно не можете получить его локально, только связавшись с внешней службой, которая сообщит вам, откуда вы подключились.Ваша ссылка является примером такой услуги.

...