2010-04-20 218 views
28

我正在尋找一種獲取本地IP地址的便攜方式。因爲我正在使用Boost,所以我認爲在這個任務中使用Boost.Asio是一個好主意。使用Boost.Asio獲取本地IP地址

在網上有幾個應該做的伎倆。例子:

Official Boost.Asio Documentation

Some Asian Page

我試圖只是稍作修改兩個代碼。 Boost.Doc上的代碼被更改爲不解決「www.boost.org」,而是「localhost」或我的主機名。爲了獲得主機名,我使用了boost :: asio :: ip :: host_name()或者直接以字符串形式輸入。

此外,我寫了自己的代碼,它是上述示例和我從Boost文檔和其他示例中收集的(小)知識的合併。

所有來源的工作,但他們所做的僅僅是返回以下IP:
127.0.1.1(這不是一個錯字,其.1.1末)
我運行,並與GCC編譯4.4在Ubuntu 9.10的代碼0.1

一位同事嘗試相同的代碼他的機器上,並得到了
127.0.0.2(不是筆誤太...)
他編寫和在SUSE 11.0 GCC 4.4.1運行(我不是100%肯定)

我不知道是否有可能改變本地主機(1 27.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; 
} 
+13

AFAIK,ASIO沒有提供枚舉機器接口的方法(Linux上的SIOCGIFCONF ioctl或Windows上的GetAdaptersAddresses),這看起來似乎是您所追求的。 您顯示的代碼使用您計算機的主機名查詢DNS,這不是一回事,因爲它更依賴於您的網絡配置(尤其是DNS必須「知道」您計算機的名稱),所以它不夠健壯。 – 2010-04-20 13:17:38

+0

asio :: ip :: address_v4 :: loopback()是否滿足您的需求? – yanpas 2016-06-08 20:27:24

回答

4

如果您編輯/ etc/hosts文件(這是* nix中只是,可能會爲窗口工作太...我不確定)你可以糾正這個問題。

主機內部文件,你會發現這樣的:(這是Ubuntu的,請注意1.1)

127.0.0.1本地主機
127.0.1.1 yourPcName.yourNetwork.tld

如果更改此文件來

127.0.0.1本地主機
127.0.1.1 yourPcName.yourNetwork.tld
your.real.ip.here yourPcName

那麼主機名應該正確解析。

測試正確解析的一種方法是使用「hostname -i」命令,該命令應該在更改主機之前錯誤地打印您的IP地址,然後再正確地打印您的IP地址。

當然這是動態IP的可怕解決方案......呃。

+1

感謝您的提示。顯然,Boost.Asio只是在使用* nix系統時讀取這些值。它適用於Ubuntu 9.10,10.04和Suse 11.2。 – MOnsDaR 2010-06-09 10:37:38

6

這是我從python網絡編程(谷歌)學到的一個技巧,來找出我機器的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; 

} 
+3

這是**不**你的IP根據谷歌..這是您的機器上配置的接口的IP。 – unixman83 2012-04-18 14:17:42

+1

這就是我們需要的本地IP地址。由於@MOnsDaR說ifconfig/ipconfig返回的那個。 它適用於我的特殊情況,當我有其他機器連接。 – fantastory 2012-11-22 13:13:20

5

您可以使用您發佈的代碼找到「您的」地址。但是...它變得複雜。可能有多個NIC,可能有LAN和WAN地址,有線和無線,環回......在我的桌面上,我有一個NIC,但兩個ips在這裏從我的局域網上的兩個diff DHCP服務器...

我找到最好讓用戶提供綁定的IP作爲命令行參數。是的,這是一個便攜式解決方案! :-)