Подтвердить что ты не робот

Получить локальный IP-адрес с помощью Boost.Asio

В настоящее время я ищу портативный способ получения локальных IP-адресов. Поскольку я использую Boost в любом случае, я подумал, что было бы неплохо использовать Boost.Asio для этой задачи.

В сети есть несколько примеров, которые должны сделать трюк. Примеры:

Официальная документация Boost.Asio

Некоторая азиатская страница

Я пробовал оба кода с небольшими изменениями. Код на Boost.Doc был изменен, чтобы не разрешать "www.boost.org", но "localhost" или мое имя хоста. Для получения имени хоста я использовал boost:: asio:: ip:: host_name() или ввел его непосредственно в виде строки.

Кроме того, я написал свой собственный код, который был слиянием приведенных выше примеров и моих (небольших) знаний, полученных мной из документации Boost и других примеров.

Все источники работали, но они просто вернули следующий IP:
127.0.1.1 (Это не опечатка, ее .1.1 в конце)
Я запустил и скомпилировал код на Ubuntu 9.10 с GCC 4.4.1

Коллега попробовал тот же код на своей машине и получил
127.0.0.2 (Не слишком опечатка...)
Он скомпилирован и работает на Suse 11.0 с GCC 4.4.1 (я не уверен на 100%)

Я не знаю, можно ли изменить localhost (127.0.0.1), но я знаю, что ни я, ни мой коллега не сделали этого. ifconfig говорит, что loopback использует 127.0.0.1. ifconfig также находит открытый IP-адрес, который я ищу (141.200.182.30 в моем случае, подсеть 255.255.0.0)

Итак, это проблема Linux, и код не такой портативный, как я думал? Нужно ли мне что-то менять или Boost.Asio не работает как решение для моей проблемы?

Я знаю, что есть много вопросов по подобным темам в Stackoverflow и других страницах, но я не могу найти информацию, которая полезна в моем случае. Если у вас есть полезные ссылки, было бы неплохо, если бы вы могли указать на него.

PS: Вот модифицированный код, который я использовал в Boost.Doc:

#include <boost/asio.hpp>
using boost::asio::ip::tcp;    

boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(boost::asio::ip::host_name(), "");
tcp::resolver::iterator iter = resolver.resolve(query);
tcp::resolver::iterator end; // End marker.
while (iter != end)
{
    tcp::endpoint ep = *iter++;
    std::cout << ep << std::endl;
}
4b9b3361

Ответ 1

Вот трюк, который я узнал из сетевого программирования python (google), чтобы выяснить мой IP-адрес машины. Это работает только в том случае, если у вас есть подключение к Интернету и вы можете подключиться к google.com и предоставить мне мой домашний адрес 192.168.x.x.

try {
    boost::asio::io_service netService;
    udp::resolver   resolver(netService);
    udp::resolver::query query(udp::v4(), "google.com", "");
    udp::resolver::iterator endpoints = resolver.resolve(query);
    udp::endpoint ep = *endpoints;
    udp::socket socket(netService);
    socket.connect(ep);
    boost::asio::ip::address addr = socket.local_endpoint().address();
    std::cout << "My IP according to google is: " << addr.to_string() << std::endl;
 } catch (std::exception& e){
    std::cerr << "Could not deal with socket. Exception: " << e.what() << std::endl;

 }

Ответ 2

Вы можете найти "свой" адрес с кодом, который вы опубликовали. НО... это усложняется. Могут быть несколько сетевых адаптеров, могут быть адреса ЛВС и WAN, проводные и беспроводные, loopback... На моем рабочем столе у ​​меня была одна сетевая карта, но два ips здесь с двух разных DHCP-серверов на моем компьютере...

Я обнаружил, что лучше дать пользователю предоставить IP-адрес для привязки в качестве параметра командной строки. И да, это портативное решение!: -)

Ответ 3

Если вы редактируете файл /etc/hosts (это только * nix, может работать и для окон... я не уверен), вы можете исправить эту проблему.

Внутри файла hosts вы найдете что-то вроде: (это Ubuntu, обратите внимание на 1.1)

127.0.0.1 localhost
127.0.1.1 yourPcName.yourNetwork.tld

если вы измените этот файл на

127.0.0.1 localhost
127.0.1.1 yourPcName.yourNetwork.tld
your.real.ip.here yourPcName

тогда имя хоста должно быть правильно разрешено.

Один из методов проверки правильного разрешения - это команда "hostname -i", которая должна неправильно печатать ваш IP-адрес перед сменой хостов, а затем правильно после этого.

Конечно, это ужасное решение для динамических IP-адресов... ах.