2010-04-20 2234 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作为命令行参数。是的,这是一个便携式解决方案! :-)