Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用Boost.Asio获取本地IP地址_C++_Ip Address_Boost Asio - Fatal编程技术网

C++ 使用Boost.Asio获取本地IP地址

C++ 使用Boost.Asio获取本地IP地址,c++,ip-address,boost-asio,C++,Ip Address,Boost Asio,我目前正在寻找一种获取本地IP地址的便携式方法。因为我正在使用Boost,所以我认为使用Boost.Asio来完成这个任务是个好主意 网上有几个例子可以说明这一点。示例: 我尝试了两种代码,只是做了一些轻微的修改。Doc上的代码被更改为不解析“www.Boost.org”,而是解析“localhost”或我的主机名。为了获取主机名,我使用boost::asio::ip::host\u name()或直接将其作为字符串键入 此外,我还编写了自己的代码,将上述示例与我从Boost文档和其他示例中

我目前正在寻找一种获取本地IP地址的便携式方法。因为我正在使用Boost,所以我认为使用Boost.Asio来完成这个任务是个好主意

网上有几个例子可以说明这一点。示例:

我尝试了两种代码,只是做了一些轻微的修改。Doc上的代码被更改为不解析“www.Boost.org”,而是解析“localhost”或我的主机名。为了获取主机名,我使用boost::asio::ip::host\u name()或直接将其作为字符串键入

此外,我还编写了自己的代码,将上述示例与我从Boost文档和其他示例中收集的(少量)知识结合起来

所有源代码都正常工作,但它们只返回了以下IP:
127.0.1.1(这不是打字错误,结尾是.1.1)
我使用GCC4.4.1在Ubuntu9.10上运行并编译了代码

一位同事在他的机器上尝试了相同的代码,得到了
127.0.0.2(也不是打字错误…
他使用GCC4.4.1在Suse 11.0上编译和运行(我不是100%确定)

我不知道是否可以更改localhost(127.0.0.1),但我知道我和我的同事都没有这样做。ifconfig说环回使用127.0.0.1。ifconfig还可以找到我正在搜索的公共IP(在我的例子中是141.200.182.30,子网是255.255.0.0)

那么这是否是Linux的问题,代码是否不像我想象的那样可移植?我是否必须改变一些其他的东西,或者我根本就不能解决我的问题

我知道在Stackoverflow和其他页面上有很多关于类似主题的问题,但我找不到对我来说有用的信息。如果你有有用的链接,如果你能给我指一下就好了

附言: 下面是我在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;
}
#包括
使用boost::asio::ip::tcp;
boost::asio::io_服务io_服务;
tcp::解析器解析器(io_服务);
tcp::resolver::query查询(boost::asio::ip::host_name(),“”);
tcp::resolver::iterator iter=resolver.resolve(查询);
tcp::解析器::迭代器端;//结束标记。
while(iter!=结束)
{
tcp::endpoint ep=*iter++;

std::cout如果编辑/etc/hosts文件(这只是*nix,可能也适用于windows…我不确定),则可以更正此问题

在hosts文件中,您会发现如下内容:(这是Ubuntu,请注意1.1)

127.0.0.1本地主机
127.0.1.1 yourpname.yourNetwork.tld

如果将此文件更改为

127.0.0.1本地主机
127.0.1.1 yourpname.yourNetwork.tld
你的.real.ip.这是你的名字

然后主机名应该正确解析

测试正确分辨率的一种方法是使用“hostname-i”命令,该命令应在更改主机之前正确打印ip地址,然后再正确打印


当然,对于动态ip来说,这是一个糟糕的解决方案……呃。

我从python网络编程(google)中学到了一个诀窍,可以算出我的机器的ip地址。只有当你有internet连接,可以连接到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;

 }
试试看{
boost::asio::io_服务netService;
udp::解析器解析器(netService);
udp::resolver::query查询(udp::v4(),“google.com”,“”);
udp::resolver::迭代器端点=resolver.resolve(查询);
udp::endpoint ep=*端点;
udp::套接字(netService);
插座连接(ep);
boost::asio::ip::addr=socket.local_endpoint().address();
std::cout你可以用你发布的代码找到“你的”地址。但是…它变得复杂了。可能有多个NIC,可能有LAN和WAN地址,有线和无线,环回…在我的桌面上,我有一个NIC,但有两个IP,来自LAN上的两个不同DHCP服务器


我发现最好让用户提供绑定到的IP作为命令行参数。是的,这是一个可移植的解决方案!:-)

跨平台,但这只是因为
\ifdef\u WIN32…\else

boost::asio::ip::address_v6 sinaddr_to_asio(sockaddr_in6*addr){
boost::asio::ip::address\u v6::bytes\u type buf;
memcpy(buf.data(),addr->sin6_addr.s6_addr,sizeof(addr->sin6_addr));
返回boost::asio::ip::make_address_v6(buf,addr->sin6_scope_id);
}
#如果已定义(_WIN32)
#未定义UNICODE
#包括
//winsock2.h之后需要包含的标题:
#包括
#包括
typedef IP_适配器_单播_地址_左地址;
typedef IP_适配器地址*地址列表;
std::vector get_local_interfaces(){
//这是一台windows机器,我们假设它有512KB的可用内存
德沃德(弗伦=1下一个){
如果(addr->OperStatus!=IfOperStatusUp)继续;
//如果(addr->NoMulticast)继续;
//查找第一个IPv4地址
如果(地址->已启用IPV4){
对于(Addr*uaddr=Addr->FirstUnicastAddress;uaddr!=0;uaddr=uaddr->Next){
如果(uaddr->Address.lpSockaddr->sa_family!=AF_INET)继续;
res.push_back(boost::asio::ip::make_address_v4(ntohl(reinterpret_cast(addr->ifa_addr)->sin_addr.s_addr));
}
}
如果(地址->IPV6已启用){
对于(Addr*uaddr=Addr->FirstUnicastAddress;uaddr!=0;uaddr=uaddr->Next){
如果(uaddr->Address.lpSockaddr->sa_family!=AF_INET6)继续;
res.push_back(sinaddr_to_asio(reinterpret_cast(addr->ifa_addr)));
}
}
}
}否则{
}
删除[](字符*)IFADRS;
返回res;
}
#elif已定义(uu APPLE_uuu)|已定义(u linux_uuuu)
#包括
#包括
#包括
#包括
std::vector get_local_interfaces(){
std::向量res;
IFADRS*国际单项体育联合会;
如果(获取IFADRS和ifs)){
返回res;
}
对于(自动添加=ifs;添加!=nullptr;添加=addr->ifa\U next){
//没有地址?跳过。
如果(addr->ifa_addr==nullptr)继续;
//
#include <boost/asio.hpp>
namespace ip = boost::asio::ip;

std::string getAddress()
{
    boost::asio::io_service ioService;
    ip::tcp::resolver resolver(ioService);

    return resolver.resolve(ip::host_name(), "")->endpoint().address().to_string();
}