web-dev-qa-db-ja.com

Boost.Asioを使用してローカルIPアドレスを取得する

現在、ローカル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(タイプミスでもない...)
彼はGCC 4.4.1を使用してSuse 11.0でコンパイルして実行しました(100%確実ではありません)

ローカルホスト(127.0.0.1)を変更できるかどうかはわかりませんが、私も同僚もそれを変更できなかったことを知っています。 ifconfigはループバックが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;
}
30
MOnsDaR

これは私がpythonネットワークプログラミング(google)から学んだトリックで、私のマシンのIPアドレスを把握するためのものです。これは、インターネット接続があり、google.comに接続できる場合にのみ機能し、自宅のマシンの192.168.xxプライベートアドレス。

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;

 }
7
SJL

あなたが投稿したコードで「あなたの」アドレスを見つけることができます。しかし...それは複雑になります。複数のNICがあるかもしれません、LANがあるかもしれませんWANアドレス、有線および無線、ループバック...私のデスクトップでは1つNICが2つのIPここに私のLAN上の2つの差分DHCPサーバーから...

ユーザーにバインドするIPをコマンドラインパラメータとして提供する方がよいことがわかりました。そして、はい、それはポータブルなソリューションです! :-)

5
moodboom

/ etc/hostsファイルを編集する場合(これは* nixのみであり、Windowsでも機能する可能性があります...わからない)この問題を修正できます。

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

その後、ホスト名は適切に解決されます。

適切な解決をテストする1つの方法は、「hostname -i」コマンドを使用することです。このコマンドは、ホストを変更する前にIPアドレスを誤って出力し、その後正しく印刷するはずです。

もちろん、これは動的IPの恐ろしい解決策です...ええ。

4
user361756