boost asio 是一個輕量級的異步網絡庫,它有簡潔,小巧,高效,有良好的可擴展性,支持高并發的IO處理,入門簡單等諸多優點。boost asio在設計上采用和和ace相似的反應器(proactor)設計模式,同時內置了對多線程的支持,針對不同的平臺,采用了最優的socket模型,可以說能發揮機器的最大并發處理能力。同時在設計上,asio在接口上也有良好的可擴展性,幾乎每種設計元素都可以根據要求訂制和擴充,可以進一步對模型進行抽象和建模來建立自己需要的開發平臺。當然,asio的最大缺點就是代碼調試太難了。
我們看一個asio的hello world:
#include
#include
#include
void print(const boost::asio::error& /*e*/)
{
std::cout << "Hello, world!\n";
}
int main()
{
// 定義一個io_service,它的作用是注冊服務,調用一個異步請求完成后對應的操作(一個handle)
boost::asio::io_service io;
//添加一個定時器服務,
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
//啟動一個異步操作,該操作會記錄于io_service 的一個隊列中
t.async_wait(print);
//每個注冊的服務啟動工作
io.run();
//5s后,定時器時間到,print被調用,然后該handle(print)從隊列中刪除
return 0;
}
可以看出,對一個使用者來說,asio的原理很簡單
1。定義一個IO_Service
2.向IO_Service注冊一個服務,該服務可以是io服務,也可以是定時器服務,當然,你也可以自己訂制一個郵件服務
3.在該服務上啟動一個異步操作,這需要一個回調函數
4.如果異步操作完成,你的回調函數會被調用
5.可能的錯誤處理
理解asio的原理后,寫一個網絡通信的程序簡直是依葫蘆畫瓢的事了
我們看一個時間查詢的服務端:
#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:
//對象建立時,注冊了udp的socket服務,接著就開始了一個異步的接收操作
udp_server(boost::asio::io_service& io_service)
: socket_(io_service, udp::endpoint(udp::v4(), 13))
{
start_receive();
}
private:
void start_receive()
{
//啟動的異步操作
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), //接收緩沖區
remote_endpoint_, //存儲請求的客戶地址,ip+port
boost::bind(&udp_server::handle_receive, this, //構造一個回調函數,實際調用了成員函數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*/)
{
//接到客戶端的信息,忽略了請求內容,直接發回本機的時間,發送也是一個異步操作
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();
}
}
//發送完成,忽略
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開發一個網絡服務端的程序一件多么簡單的事。對此程序稍加改動,我們就可以建立一個支持多線程,高并發的網絡服務程序。
后面我們將繼續分析asio的多線程支持,多緩沖,網絡流等更好的基礎特性。