Boost.Asio 筆記

來源:互聯網
上載者:User

《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 2001ip::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_errortry{    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 closedboost/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 onWindows, 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()函數始終啟動並執行方法 在回呼函數中執行新的非同步作業 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();

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.