19.0 基于ASIO网络编程技术

Boost ASIO库是一个基于C++语言的开源网络编程库,该库提供了成熟、高效、跨平台的网络API接口,并同时支持同步与异步两种模式,ASIO库提供了多重I/O对象、异步定时器、可执行队列、信号操作和协程等支持,使得开发者可以轻松地编写可扩展的高性能网络应用程序,同时保持代码简洁、易于维护。

在学习ASIO库之前,我们先来实现一个简单的地址解析功能,Boost库中提供了ip::tcp::resolver对象,该对象可用于解析给定主机名和端口号的IP地址,学会使用这个对象即可实现对特定主机域名地址的解析功能,如下封装实现了GetDNSAddress该函数传入一个域名,并输出该域名所对应的IP地址列表,并返回给std::vector容器内,其实现原理如下所示;

#include <iostream>
#include <vector>
#include <boost/asio.hpp>

using namespace std;
using namespace boost;
using namespace boost::asio;

// 传入域名解析IP地址
std::vector<std::string> GetDNSAddress(std::string hostname)
{
std::vector<std::string> address_list;
boost::asio::io_service ioservice;
boost::asio::io_service my_io_service;
boost::asio::ip::tcp::resolver resolver(my_io_service);
boost::asio::ip::tcp::resolver::query query(hostname, "https");
boost::asio::ip::tcp::resolver::iterator iter = resolver.resolve(query);
boost::asio::ip::tcp::resolver::iterator end;

while (iter != end)
{
boost::asio::ip::tcp::endpoint endpoint = *iter++;
address_list.push_back(endpoint.address().to_string());
}
return address_list;
}

这段代码的调用很容易,只需要传入特定域名即可,如下所示代码中,我们获取www.baidu.com域名下所有的IP地址列表,并依次循环输出ref_address_list中的所有列表信息。

int main(int argc, char *argv[])
{
// 从字符串产生IP
ip::address addr;
addr = addr.from_string("192.168.1.1");

if (addr.is_v4())
{
std::string addr_string = addr.to_string();
std::cout << "IP地址: " << addr_string << std::endl;
}

// 根据域名获取所有DNS地址
std::vector < std::string > ref_address_list;
ref_address_list = GetDNSAddress("www.baidu.com");
for (int x = 0; x < ref_address_list.size(); x++)
{
std::cout << ref_address_list[x] << std::endl;
}

std::system("pause");
return 0;
}

读者可自行编译并运行上述代码片段,当运行后会看到特定域名下所包含的所有IP信息,如下图所示;