您的位置:首页 > 其它

Boost::asio 学习笔记

2015-08-13 15:25 459 查看

一 、简介

boost asio 是个一由C++编写的、 跨平台的、 使用现代化C++方法的、 提供了统一的异步模型的网络和底层I/O 开发库。

Boost.Asio is a cross-platform C++ library for network and low-level I/O programming that provides developers with a consistent asynchronous model using a modern C++ approach.

二 、各部分功能

1. io_service

个人理解 : io_service 就是boost::asio 基于OS的I/O引擎, 其他的功能是建立在它之上的 。

io_service 拥有所有异步I/O对象( socket 、 deadline_timer … ) 需要的核心I/O功能 。 包括 :

boost::asio::ip::tcp::socket

boost::asio::ip::tcp::acceptor

boost::asio::ip::udp::socket

deadline_timer.

主要接口

run()
运行时间驱动循环
run_one()
在一个handler处理后退出。

poll()
运行已经就绪的handler ,
poll_one
只处理一个。

多线程安全

io_service 大部分情况下是安全的, 除了
reset()
notify_fork()
两个接口。

使用
work
终止无限的
run()
接口

boost::asio::io_service io_service;
auto_ptr<boost::asio::io_service::work> work(new boost::asio::io_service::work(io_service));
...
work.reset(); // Allow run() to exit.


2. resolver 和 endpoint

个人理解 : resolver 接管了DNS, 将开发者的查询(query) 转换为endpoint ( IP:Port) 地址。

resolver::query
保存用户查询, 可以使主机名+服务命, 可以是单独的服务名, 可以是单独的主机名 …

示例代码 ( 仅tcp)

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

int main()
{
boost::asio::io_service ios;
boost::asio::ip::tcp::resolver re(ios);
boost::asio::ip::tcp::resolver::query q("www.baidu.com", "http");
boost::asio::ip::tcp::endpoint ee= *re.resolve(q);
std::cout<<ee << "\n";
boost::asio::ip::tcp::resolver::query q1("www.baidu.com", "https");
boost::asio::ip::tcp::endpoint ee1= *re.resolve(q1);
std::cout<<ee1 << "\n";
boost::asio::ip::tcp::resolver::query q2("daytime");
boost::asio::ip::tcp::endpoint ee2= *re.resolve(q2);
std::cout<<ee2 << "\n";
return 0;
}


输出 :

115.239.210.27:80

115.239.210.27:443

0.0.0.0:13

3. Socket

Socket 分为 tcp 、 udp 、imcp 等

收发接口

同步

read_some()
receive()


write_some()
send()


异步

async_read_some()
async_receive()


async_write_some()
async_send()


注意 : 这八个接口并不保证接收足量的数据,如果需要读写一定数目后才响应, 需要使用非成员函数:

read()  write()


async_read()  async_write()


4 Buffer

Buffer 是用来存储缓存二进制数据块的地方。

mutable_buffer


const_buffer


buffer 支持 + 运算符 :

buffer +1 意味着产生一个新的buffer, 这个buffer从原来的buffer的 offset = 1 处复制到最后!!!

read*
write*
接口并不直接接收
XXX_buffer
, 它们介绍的是buffer的序列。

也就是以容器(vector 、 list) 装载的
XXX_buffer


单个的
XXX_buffer
可以转化
XXX_buffers_1
来被传递。

常用的接口:

buffer()
接口将
std::array , vector of POD, string
等转换为buffer序列。

buffer_size()
接口获取数据大小

buffer_copy()
copy 之

buffer_cast()
接口返回底层内存地址 ! 类似
array
data()
接口.

5 一个ECHO的服务器客户端实现

server.cpp

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

static int i = 0;

class TcpConn : private boost::noncopyable,
public std::enable_shared_from_this<TcpConn>
{
public:
TcpConn( boost::asio::io_service &ios ) : sock__(ios) { i++ ;std::cout<<"Curr i is : "<<i<<"\n";}
~TcpConn() { i-- ; std::cout<<"Curr i is : "<<i<<"\n";}
void StartEcho();
void Echo( boost::system::error_code e );
boost::asio::ip::tcp::socket & GetSocket() { return  sock__;}
private:
std::array<char , 1024>  buf__;
boost::asio::ip::tcp::socket  sock__;
};

void TcpConn::StartEcho()
{
try{
sock__.write_some(boost::asio::buffer("ECHO :\n"));
buf__.fill(0);
sock__.async_read_some( boost::asio::buffer(buf__), std::bind(&TcpConn::Echo , shared_from_this() ,std::placeholders::_1 ));
}catch( ... ) {
std::cout<<"sock error\n";
}
}

void TcpConn::Echo( boost::system::error_code e )
{
if(!e)
{
boost::asio::mutable_buffer tmp(buf__.data() , buf__.size());
tmp = tmp ;
sock__.write_some(boost::asio::mutable_buffers_1(tmp));
}
StartEcho();
}
class TcpServer
{
public:
TcpServer(boost::asio::io_service &ios,boost::asio::ip::tcp::endpoint  end ) : accp__(ios ,end) , ios__(ios) { StartAccept() ; }
void StartAccept();
void DealConn(std::shared_ptr<TcpConn>, boost::system::error_code );
private:
boost::asio::ip::tcp::acceptor  accp__;
boost::asio::io_service  & ios__;
};

void TcpServer::StartAccept()
{
std::shared_ptr<TcpConn> conn_ptr = std::shared_ptr<TcpConn>(new TcpConn(ios__));
accp__.async_accept( conn_ptr->GetSocket() , std::bind(&TcpServer::DealConn,this,conn_ptr, std::placeholders::_1));
}

void TcpServer::DealConn(std::shared_ptr<TcpConn> ptk, boost::system::error_code e)
{
if(!e)
{
ptk->StartEcho();
}
StartAccept();
}

int main(){
// A io_service to connect platform
boost::asio::io_service  io_platform;
// A tcp resolver to resolve the tcp address
boost::asio::ip::tcp::resolver  res(io_platform);
// A queue to save the address [ ip and port ]
boost::asio::ip::tcp::resolver::query q("192.168.1.252", "89910");
// res resolve the address q
boost::asio::ip::tcp::endpoint endp = *(res.resolve(q));

// A tcp accepter
TcpServer tcp(io_platform,endp );
io_platform.run();
//Never come here
return 0;
}


client.cpp

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

int main(){
// A io_service to connect platform
boost::asio::io_service  io_platform;
// A tcp resolver to resolve the tcp address
boost::asio::ip::tcp::resolver  res(io_platform);
// A queue to save the address [ ip and port ]
boost::asio::ip::tcp::resolver::query q("192.168.1.252", "89910");
boost::asio::ip::tcp::socket sock(io_platform );
boost::asio::connect(sock,res.resolve(q) );
do {
std::string a;
std::string b;
std::string c;
std::array<char , 1024>  char_buf_1 ;
char_buf_1.fill(0);
sock.read_some(boost::asio::buffer(char_buf_1));
std::cout<<char_buf_1.data()<<"\n";
char_buf_1.fill(0);
std::cout<<"a :";
std::cout.flush();
std::cin>>a;
std::cout<<"b :";
std::cout.flush();
std::cin>>b;
std::cout<<"c :";
std::cout.flush();
std::cin>>c;
boost::system::error_code err;
std::vector<boost::asio::mutable_buffer> buff ;
buff.push_back(boost::asio::mutable_buffer((void*)a.c_str(), a.size()));
buff.push_back(boost::asio::mutable_buffer((void*)b.c_str(), b.size()));
buff.push_back(boost::asio::mutable_buffer((void*)c.c_str(), c.size()));
sock.write_some( buff );
boost::asio::read(sock,boost::asio::buffer(char_buf_1));
std::cout<<char_buf_1.data()<<"\n";
}while(2);

//Never come here
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: