Boost.Asio 笔记

原创 2017年06月23日 01:19:30

《Boost.Asio C++ Network Programming》

libtorrent使用了Boost.Asio

支持
network
com serial ports
files

实现同步/异步输入输出
read(stream, buffer)
async_read(stream, buffer)
write(stream, buffer)
async_write(stream, buffer)

TCP UDP IMCP
可以根据自己的需要扩展使其支持自己的协议

如果使用同步模式,因为是阻塞模式,所以服务器客户端往往使用多线程

编程前尽早决定使用同步还是异步模式
异步模式调试更困难

  • 同步多线程
  • 异步单线程

例:同步客户端

using boost::asio;
io_service service;
ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1", 2001);
ip::tcp::socket(service);
sock.connect(ep);

Boost.Asio uses io_service to talk to the operating system’s input/output services.

同步服务器

using boost::asio;
typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;
io_service service;
ip::tcp::endpoint ep(ip::tcp::v4(), 2001)); // listen on 2001
ip::tcp::acceptor acc(service, ep);
while (true)
{
    socket_ptr sock(new ip::tcp::socket(service));
    acc.accept(*sockt);
    boost::thread(boost::bind(client_session, sock);
}
void client_session(socket_ptr sock)
{
    while (true)
    {
        char data[512];
        size_t len = sock->read_some(buffer(data));
        if (len > 0)
            write(*sock, buffer("ok", 2));
    }
}

异步客户端

using boost::asio;
io_service service;
ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1", 2001);
ip::tcp::socket sock(service);
sock.async_connect(ep, connect_handler);
service.run();

void connect_handler(const boost::system::error_code& ec)
{
    // here we known we connected successfully
    // if ec indicates success
}

// service.run() 直到所有异步操作完成才退出

异步服务器

using boost::asio;
typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;
io_service service;
ip::tcp::endpoint ep(ip::tcp::v4(), 2001);
ip::tcp::acceptor acc(service, ep);
socket_ptr sock(new ip::tcp::socket(service));
start_accept(sock);
service.run();

void start_accept(socket_ptr sock)
{
    acc.async_accept(*sock, boost::bind(handle_accept, sock, _1));
}

void handle_accept(socket_ptr sock, const boost::system::error_code& err)
{
    if (err) 
        return;

    // at this point, you can read/write to the socket

    socket_ptr sock(new ip::tcp::socket(service));
    start_accept(sock);
}

异常处理

using boost::asio;
ip::tcp::endpoint ep;
ip::tcp::socket sock(service);
// 抛出异常 boost::system::system_error
try
{
    sock.connect(ep);
} catch (boost::system::system_error& e)
{ std::cout << e.code() << std::endl; }
boost::system::error_code err;
// 返回错误代码
sock.connect(ep, err);
if (err)
    std::cout << err << std::endl;

异步模式始终返回错误代码,异步函数不会抛出异常。

char data[512];
boost::system::error_code error;
size_t length = sock.read_some(buffer(data), error);
if (error == error::eof)
    return; // Connection closed
boost/asio/error.hpp

io_service 是线程安全的。
多个线程可以调用io_service::run()
回调函数会在任意一个调用run()的线程中执行。

socket类不是线程安全的
应该避免一个线程读另一个线程写同一个socket

utility 用在多个线程中是没有意义的,所以不是线程安全的。
Most of them are meant to just be used for a short time, then
go out of scope.

除了网络之外:
信号

void signal_handler(const boost::system::error_code & err, int signal)
{
// log this, and terminate application
}
boost::asio::signal_set sig(service, SIGINT, SIGTERM);
sig.async_wait(signal_handler);

串口

Using Boost.Asio, you can easily connect to a serial port. The port name is COM7 on
Windows, or /dev/ttyS0 on POSIX platforms:
io_service service;
serial_port sp(service, "COM7");
serial_port::baud_rate rate(9600);
sp.set_option(rate);

其他详见Boost.Asio C++ Network Programming.pdf 14页

计时器

sock.async_read_some(buffer(data, 512));
deadline_timer t(service, boost::posix_time::milliseconds(100));
t.async_wait(&deadline_handler);
service.run();

同步计时器和sleep等价

boost::this_thread::sleep(500);
// -or-
deadline_timer t(service, boost::posix_time::milliseconds(500));
t.wait();

以下代码没有意义,多个service实例运行在同一个线程中
因为service_[1].run()需要等待service_[0].run()完成。

for ( int i = 0; i < 2; ++i)
    service_[i].run();

1.
线程1 s.run() 所有回调函数的调用在该线程中是同步的
2.
线程1 s.run() 所有回调函数会被分配到多个线程异步执行
线程2 s.run()
3.
线程1 s1.run()
线程2 s2.run()

使run()函数始终运行的方法

  1. 在回调函数中执行新的异步操作
  2. The other way is to simulate some work for it,
    by using the following code snippet:
    typedef boost::shared_ptr work_ptr;
    work_ptr dummy_work(new io_service::work(service_));
    The preceding code will make sure that service_.run()never stops unless you
    either use service_.stop() or dummy_work.reset(0); // destroy dummy_work.
// service.post()

io_service::strand strand_one(service);
service.post(strand_one.wrap(boost::bind(func, i)));

service.dispatch()
如果当前进程调用了run(),dispatch()将等待,直达任务被执行完毕。
post()是立即返回

boost::function

boost::thread_group threads;
threads.create_thread(func1);
threads.create_thread(func2);
threads.join_all();

硬盘故障时无法关机:bash: /sbin/shutdown: Input/output error

转自:http://blog.csdn.net/u010022051/article/details/51011734 如果硬盘可能会出现锁死或坏道的故障,会造成SHELL命令的失效,包括reb...
  • worker_1983
  • worker_1983
  • 2016年11月21日 10:14
  • 373

Linux - 标准输入(input)\输出(output)\错误(error) 详解

标准输入(input)\输出(output)\错误(error) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/2393...
  • u012515223
  • u012515223
  • 2014年04月17日 15:17
  • 4683

boost_1_48_0 在VS2008下的安装 Boost.Asio安装

第一步:到官网www.boost.org,下载boost最新版boost_1_48_0.zip   第二步:将boost压缩包解压到C盘根目录下(在C盘操作简单,不会出错),目录为...
  • GUANYIJUN123
  • GUANYIJUN123
  • 2015年01月09日 08:38
  • 841

Boost.Asio c++ 网络编程翻译(30)[完结]

PS:至此终于完成了Boost.Asio C++ network programming一书的翻译,这是我人生第一本完整翻译的书,从开始的磕磕绊绊,到最后小有心得,我收获很多。我将把这个系列的博客进行...
  • mmoaay
  • mmoaay
  • 2014年11月26日 08:56
  • 3864

linux input/output error

在操作linux系统的时候有时候会遇到这个错误提示,那么首先要确定之前有没有操作过分区表,修改过磁盘配置等。尤其在虚拟机环境下改动后直接操作都会出现这个错误,此时尝试以下方法: 1. reboot  ...
  • JAZZSOLDIER
  • JAZZSOLDIER
  • 2017年01月21日 17:19
  • 3689

Boost::Asio::Error的用法浅析

一般而言我们创建用于接收error的类型大多声明如下:  boost::system::error_code error 我们用这个类型去接受在函数中产生的错误 如 socket.co...
  • bravegogo
  • bravegogo
  • 2016年03月17日 10:59
  • 500

Boost.Asio C++ Network Programming翻译的校对稿

Boost.Asio C++ Network Programming翻译的校对稿将发布在gitbook上:https://www.gitbook.com/book/mmoaay/boost-asio-...
  • mmoaay
  • mmoaay
  • 2014年12月25日 09:05
  • 3541

QT使用asio

ASIO有两个版本,一个必须依赖BOOST,这玩意真把我搞晕乎了,怎么都没弄好。百度发现有另一个版本Standalone,网址http://think-async.com/,下载了解压到某个目录,然后...
  • binxuan7
  • binxuan7
  • 2018年01月01日 23:59
  • 39

Cannot remove : Input/output error

有一个ext3的根文件系统,里面有个临时文件,
  • CaspianSea
  • CaspianSea
  • 2014年09月18日 21:09
  • 7727

python2.7出现IOError: [Errno 5] Input/output error

你会发现,出现这种报错的时候,一定是在print语句地方报这种错。 直接注释掉就行了...
  • appleyuchi
  • appleyuchi
  • 2017年12月09日 21:25
  • 575
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Boost.Asio 笔记
举报原因:
原因补充:

(最多只允许输入30个字)