Boost::asio 学习笔记

一 、简介

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() 接口返回底层内存地址 ! 类似arraydata()接口.

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值