boost asio 是一個(gè)輕量級(jí)的異步網(wǎng)絡(luò)庫(kù),它有簡(jiǎn)潔,小巧,高效,有良好的可擴(kuò)展性,支持高并發(fā)的IO處理,入門簡(jiǎn)單等諸多優(yōu)點(diǎn)。boost asio在設(shè)計(jì)上采用和和ace相似的反應(yīng)器(proactor)設(shè)計(jì)模式,同時(shí)內(nèi)置了對(duì)多線程的支持,針對(duì)不同的平臺(tái),采用了最優(yōu)的socket模型,可以說(shuō)能發(fā)揮機(jī)器的最大并發(fā)處理能力。同時(shí)在設(shè)計(jì)上,asio在接口上也有良好的可擴(kuò)展性,幾乎每種設(shè)計(jì)元素都可以根據(jù)要求訂制和擴(kuò)充,可以進(jìn)一步對(duì)模型進(jìn)行抽象和建模來(lái)建立自己需要的開發(fā)平臺(tái)。當(dāng)然,asio的最大缺點(diǎn)就是代碼調(diào)試太難了。
我們看一個(gè)asio的hello world:
#include
#include
#include
void print(const boost::asio::error& /*e*/)
{
std::cout << "Hello, world!\n";
}
int main()
{
// 定義一個(gè)io_service,它的作用是注冊(cè)服務(wù),調(diào)用一個(gè)異步請(qǐng)求完成后對(duì)應(yīng)的操作(一個(gè)handle)
boost::asio::io_service io;
//添加一個(gè)定時(shí)器服務(wù),
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
//啟動(dòng)一個(gè)異步操作,該操作會(huì)記錄于io_service 的一個(gè)隊(duì)列中
t.async_wait(print);
//每個(gè)注冊(cè)的服務(wù)啟動(dòng)工作
io.run();
//5s后,定時(shí)器時(shí)間到,print被調(diào)用,然后該handle(print)從隊(duì)列中刪除
return 0;
}
可以看出,對(duì)一個(gè)使用者來(lái)說(shuō),asio的原理很簡(jiǎn)單
1。定義一個(gè)IO_Service
2.向IO_Service注冊(cè)一個(gè)服務(wù),該服務(wù)可以是io服務(wù),也可以是定時(shí)器服務(wù),當(dāng)然,你也可以自己訂制一個(gè)郵件服務(wù)
3.在該服務(wù)上啟動(dòng)一個(gè)異步操作,這需要一個(gè)回調(diào)函數(shù)
4.如果異步操作完成,你的回調(diào)函數(shù)會(huì)被調(diào)用
5.可能的錯(cuò)誤處理
理解asio的原理后,寫一個(gè)網(wǎng)絡(luò)通信的程序簡(jiǎn)直是依葫蘆畫瓢的事了
我們看一個(gè)時(shí)間查詢的服務(wù)端:
#include
#include
#include
#include
#include
#include
#include
using boost::asio::ip::udp;
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&now);
}
class udp_server
{
public:
//對(duì)象建立時(shí),注冊(cè)了udp的socket服務(wù),接著就開始了一個(gè)異步的接收操作
udp_server(boost::asio::io_service& io_service)
: socket_(io_service, udp::endpoint(udp::v4(), 13))
{
start_receive();
}
private:
void start_receive()
{
//啟動(dòng)的異步操作
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), //接收緩沖區(qū)
remote_endpoint_, //存儲(chǔ)請(qǐng)求的客戶地址,ip+port
boost::bind(&udp_server::handle_receive, this, //構(gòu)造一個(gè)回調(diào)函數(shù),實(shí)際調(diào)用了成員函數(shù)handle_receive,具體見boost::bind
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
);
}
void handle_receive(const boost::asio::error& error,
std::size_t /*bytes_transferred*/)
{
//接到客戶端的信息,忽略了請(qǐng)求內(nèi)容,直接發(fā)回本機(jī)的時(shí)間,發(fā)送也是一個(gè)異步操作
if (!error || error == boost::asio::error::message_size)
{
boost::shared_ptr message(
new std::string(make_daytime_string()));
socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_,
boost::bind(&udp_server::handle_send, this, message,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
start_receive();
}
}
//發(fā)送完成,忽略
void handle_send(boost::shared_ptr /*message*/,
const boost::asio::error& /*error*/, std::size_t /*bytes_transferred*/)
{
}
udp::socket socket_;
udp::endpoint remote_endpoint_;
boost::array recv_buffer_;
};
int main()
{
try
{
boost::asio::io_service io_service;
udp_server server(io_service);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
可以看到,用asio開發(fā)一個(gè)網(wǎng)絡(luò)服務(wù)端的程序一件多么簡(jiǎn)單的事。對(duì)此程序稍加改動(dòng),我們就可以建立一個(gè)支持多線程,高并發(fā)的網(wǎng)絡(luò)服務(wù)程序。
后面我們將繼續(xù)分析asio的多線程支持,多緩沖,網(wǎng)絡(luò)流等更好的基礎(chǔ)特性。