基于boost asio实现的支持ssl的通用socket框架
生活随笔
收集整理的這篇文章主要介紹了
基于boost asio实现的支持ssl的通用socket框架
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
情景分析
???現已存在一個可用穩定的異步客戶端類http_client_base,該類基于boost asio實現了連接服務器,發送請求,獲取響應和解析http數據等操作,該類的大致實現框架如下
??1class?http_client_base
??2{
??3public:
??4????http_client_base(boost::asio::io_service&?io_service)
??5????????:resolver_(io_service),socket_(io_service)
??6????{?
??7????}
??8????
??9????void?async_connect(const?std::string&?address,const?std::string&?port)
?10????{????
?11????????boost::asio::ip::tcp::resolver::query?query(address,?port);
?12????????resolver_.async_resolve(query,boost::bind(&http_client::handle_resolve,?this,
?13????????asio::placeholders::error,asio::placeholders::iterator));
?14????}
?15????
?16????void?async_write(const?void*?data,size_t?size,bool?in_place=false)
?17????{
?18????????if(!in_place){
?19????????????//do?something
?20????????????asio::async_write(socket_,request_,
?21????????????????????????????boost::bind(&http_client::handle_write,this,boost::asio::placeholders::error));
?22????????}else
?23????????????asio::async_write(socket_,asio::buffer(data,size),
?24????????????????????????????boost::bind(&http_client::handle_write,this,boost::asio::placeholders::error));
?25????}
?26????
?27????void?async_write_some(const?void*?data,size_t?size,bool?in_place=false)
?28????{
?29????????if(!in_place){
?30????????????//do?something
?31????????????boost::asio::async_write(socket_,request_,
?32????????????????????????????????????boost::bind(&http_client::handle_write_some,this,boost::asio::placeholders::error));
?33????????}else
?34????????????boost::asio::async_write(socket_,boost::asio::buffer(data,size),
?35????????????????????????????????????boost::bind(&http_client::handle_write_some,this,boost::asio::placeholders::error));
?36????}
?37
?38private:
?39????void?handle_resolve(const?boost::system::error_code&?e,boost::asio::ip::tcp::resolver::iterator?endpoint_iterator)
?40????{
?41????????if?(!e)
?42????????????boost::asio::async_connect(socket_,?endpoint_iterator,
?43????????????????????????????????????boost::bind(&http_client::handle_connect,this,boost::asio::placeholders::error));
?44????????else
?45????????????onIoError(e);
?46????}
?47????
?48????void?handle_connect(const?boost::system::error_code&?e)
?49????{
?50????????if(!e)
?51????????????onConnect();
?52????????else
?53????????????onIoError(e);
?54????}
?55
?56????void?handle_write_some(const?boost::system::error_code&?e)
?57????{
?58????????if(!e)
?59????????????onWriteSome();
?60????????else
?61????????????onIoError(e);
?62????}
?63
?64????void?handle_write(const?boost::system::error_code&?e)
?65????{
?66????????if(!e)
?67????????????boost::asio::async_read_until(socket_,?response_,"\r\n\r\n",
?68????????????????????????????boost::bind(&http_client::handle_read_header,this,
?69????????????????????????????boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
?70????????else
?71????????????onIoError(e);
?72????}
?73????
?74????void?handle_read_header(const?boost::system::error_code&?e,size_t?bytes_transferred)
?75????{
?76????????if(!e){
?77????????????//do?something
?78????????????boost::asio::async_read(socket_,response_,asio::transfer_at_least(1),
?79????????????????????????????boost::bind(&http_client::handle_read_content,this,
?80????????????????????????????boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred);????????????????????????????
?81????????}else
?82????????????onIoError(e);
?83????}
?84
?85????void?handle_read_content(const?boost::system::error_code&?e,size_t?bytes_transferred)
?86????{
?87????????if(!e){
?88????????????//do?something
?89????????????boost::asio::async_read(socket_,response_,asio::transfer_at_least(1),
?90????????????????????????????????boost::bind(&http_client::handle_read_content,this,
?91????????????????????????????????boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
?92????????}else
?93????????????onIoError(e);
?94????}
?95
?96protected:
?97????virtual?void?onConnect(){}
?98????virtual?void?onWriteSome(){}
?99????virtual?void?onIoError(const?boost::system::error_code&?e){}
100
101private:
102????boost::asio::ip::tcp::socket?socket_;
103????boost::asio::ip::tcp::resolver?resolver_;
104????boost::asio::streambuf?request_;
105????boost::asio::streambuf?response_;
106}; ???顯而易見,http_client_base使用tcp::socket作為底層實現,所以數據是非ssl傳輸的?,F因需求變更,為了數據安全要求使用ssl傳輸。但boost asio中的ssl::stream類接口和tcp::socket有所不同。其實在非ssl和ssl間,不同的只是讀寫數據的方法,而數據處理邏輯不變,因此為了重用http_client_base的機制框架和對http數據的解析,那么怎么使http_client_base不作大的改動就支持ssl呢?通過研究boost asio源碼發現,async_xxx系列自由函數內部要求讀寫流實現read_some、async_read_some、write_some和async_write_some4個短讀寫方法。由于tcp::socket已實現短讀寫而且ssl::stream是tcp::socket的上層,因此只要設計一個抽象的基類流,使之支持read_some、async_some_read、w rite _some和async_write_some即可,而實現使用dynamic_cast轉到兄弟基類tcp::socket或ssl::stream,再調用它們對應的同名短讀寫方法;另外還需要給出獲取最底層socket的接口,以支持async_connect和connect方法。因此針對這一設計實現,則要求派生類必須同時從抽象基類和其兄弟基類tcp::socket或ssl::stream繼承。
框架實現 ?
??1template<typename?T>
??2class?boost_socket_base
??3{
??4public:
??5????typedef?boost::asio::ssl::stream<T>?ssl_socket_base_t;
??6????typedef?T?socket_base_t;
??7
??8protected:
??9????boost_socket_base()
?10????????:tb_(boost::indeterminate)
?11????{
?12????}
?13
?14public:
?15????virtual?~boost_socket_base()?{}
?16
?17????ssl_socket_base_t*?get_ssl_socket()
?18????{
?19????????if(tb_){
?20????????????BOOST_ASSERT(ss_);????????
?21????????????return?ss_;
?22????????}else?if(!tb_)
?23????????????return?NULL;
?24????????else{
?25????????????if(ss_=dynamic_cast<ssl_socket_base_t*>(this))
?26????????????????tb_?=?true;
?27????????????return?ss_;
?28????????}?
?29????}
?30
?31????socket_base_t*?get_socket()
?32????{
?33????????if(!tb_){
?34????????????BOOST_ASSERT(s_);????????
?35????????????return?s_;
?36????????}else?if(tb_)
?37????????????return?NULL;
?38????????else{
?39????????????if(s_=dynamic_cast<socket_base_t*>(this))
?40????????????????tb_?=?false;
?41????????????return?s_;
?42????????}
?43????}
?44
?45????void?reset()
?46????{????tb_?=?boost::indeterminate;?}
?47
?48????typename?T::lowest_layer_type&?lowest_layer()
?49????{
?50????????ssl_socket_base_t*?p?=?get_ssl_socket();
?51????????if(p)?
?52????????????return?p->lowest_layer();
?53????????else
?54????????????return?get_socket()->lowest_layer();
?55????}
?56
?57????template?<typename?MutableBufferSequence>
?58????std::size_t?read_some(const?MutableBufferSequence&?buffers)
?59????{
?60????????ssl_socket_base_t*?p?=?get_ssl_socket();
?61????????if(p)?
?62????????????return?p->read_some(buffers);
?63????????else
?64????????????return?get_socket()->read_some(buffers);
?65????}
?66????
?67????template?<typename?MutableBufferSequence>
?68????std::size_t?read_some(const?MutableBufferSequence&?buffers,boost::system::error_code&?ec)
?69????{
?70????????ssl_socket_base_t*?p?=?get_ssl_socket();
?71????????if(p)?
?72????????????return?p->read_some(buffers,ec);
?73????????else
?74????????????return?get_socket()->read_some(buffers,ec);
?75????}
?76
?77????template?<typename?MutableBufferSequence,?typename?ReadHandler>
?78????void?async_read_some(const?MutableBufferSequence&?buffers,BOOST_ASIO_MOVE_ARG(ReadHandler)?handler)
?79????{
?80????????ssl_socket_base_t*?p?=?get_ssl_socket();
?81????????if(p)?
?82????????????return?p->async_read_some(buffers,handler);
?83????????else
?84????????????return?get_socket()->async_read_some(buffers,handler);
?85????}
?86
?87????template?<typename?ConstBufferSequence>
?88????std::size_t?write_some(const?ConstBufferSequence&?buffers,boost::system::error_code&?ec)
?89????{
?90????????ssl_socket_base_t*?p?=?get_ssl_socket();
?91????????if(p)?
?92????????????return?p->write_some(buffers,ec);
?93????????else
?94????????????return?get_socket()->write_some(buffers,ec);
?95????}
?96
?97????template?<typename?ConstBufferSequence>
?98????std::size_t?write_some(const?ConstBufferSequence&?buffers)
?99????{
100????????ssl_socket_base_t*?p?=?get_ssl_socket();
101????????if(p)?
102????????????return?p->write_some(buffers);
103????????else
104????????????return?get_socket()->write_some(buffers);
105????}
106
107????template?<typename?MutableBufferSequence,?typename?ReadHandler>
108????void?async_write_some(const?MutableBufferSequence&?buffers,BOOST_ASIO_MOVE_ARG(ReadHandler)?handler)
109????{????
110????????ssl_socket_base_t*?p?=?get_ssl_socket();
111????????if(p)?
112????????????return?p->async_write_some(buffers,handler);
113????????else
114????????????return?get_socket()->async_write_some(buffers,handler);
115????}
116
117private:
118????boost::tribool?tb_;
119????union?{
120????????ssl_socket_base_t*?ss_;
121????????socket_base_t*?s_;
122????};
123}; ???考慮到dynamic_cast轉換的性能開銷,因此增加了三態邏輯變量tb_和union指針,tb_表示當前this實際指向的對象類型,初始化為indeterminate,true表示ssl socket對象,使用ss_;false表示普通socket對象,使用s_。這樣一來,當且僅當tb_為indeterminate時才dynamic_cast。由于這點優化僅對基類指針操作有效,而對派生對象實無必要,所以tb_和union指針設為私有的;而且基類指針可以指向不同的子類對象,所以增加了reset方法重設tb_為indeterminate狀態,保證行為的正確性。
應用改進
???使用boost_socket_base框架后,只須5個地方稍作改動即可。
???1)成員變量 :由原來的boost::asio::ip::tcp改為boost_socket_base<boost_tcp_socket>*類型。 1typedef?boost::asio::ip::tcp::socket?boost_tcp_socket;
2boost_socket_base<boost_tcp_socket>*?socket_;
??? 2)構造函數 :增加boost::asio::ssl::context* ctx參數,默認為NULL,表示不使用ssl。
1http_client_base(boost::asio::io_service&?io_service,boost::asio::ssl::context*?ctx=NULL)
2????:resolver_(io_service)
3{
4????????if(ctx)
5????????????socket_?=?new?boost_ssl_socket<boost_tcp_socket>(io_service,*ctx);
6????????else
7????????????socket_?=?new?boost_socket<boost_tcp_socket>(io_service);
8}
??? 3)握手 處理 :與非ssl不同的是,在連接后需要進行握手,握手成功后才回調onConnect。
?1void?handle_connect(const?boost::system::error_code&?e)
?2{
?3????if(!e){
?4????????boost_socket_base<boost_tcp_socket>::ssl_socket_base_t*?p?=?socket_->get_ssl_socket();
?5????????if(p)
?6????????????p->async_handshake(boost::asio::ssl::stream_base::client,boost::bind(&http_client::handle_handshake,
?7???????????????????????????this,boost::asio::placeholders::error));
?8????????else
?9????????????onConnect();
10????}else
11????????onIoError(e);
12}
13void?handle_handshake(const?boost::system::error_code&?e)
14{
15????if(!e)
16????????onConnect();
17????else
18????????onIoError(e);
19}
??? 4)異步連接 :由于async_connect只接受boost::basic_socket類即最底層的socket作為參數,因此需要調用lowest_layer。
1void?handle_resolve(const?boost::system::error_code&?e,boost::asio::ip::tcp::resolver::iterator?endpoint_iterator)
2{
3????if?(!e)
4????????boost::asio::async_connect(socket_->lowest_layer(),?endpoint_iterator,boost::bind(&http_client::handle_connect,this,boost::asio::placeholders::error));
5????else
6????????onIoError(e);
7}
???5)async_xxx調用 :將參數socet_改為*socket_,例如下。
?1void?async_write(const?void*?data,size_t?size,bool?in_place=false)
?2{
?3????if(!in_place){
?4????????//do?something
?5????????boost::asio::async_write(*socket_,request_,boost::bind(&http_client::handle_write,this,boost::asio::placeholders::error));
?6????}else
?7????????boost::asio::async_write(*socket_,asio::buffer(data,size),boost::bind(&http_client::handle_write,this,boost::asio::placeholders::error));
?8}
?9void?handle_write(const?boost::system::error_code&?e)
10{
11????if(!e)
12????????boost::asio::async_read_until(*socket_,?response_,?"\r\n\r\n",
13????????????????????boost::bind(&http_client::handle_read_header,this,boost::asio::placeholders::error,asio::placeholders::bytes_transferred));
14????else
15????????onIoError(e);
16}
???現已存在一個可用穩定的異步客戶端類http_client_base,該類基于boost asio實現了連接服務器,發送請求,獲取響應和解析http數據等操作,該類的大致實現框架如下
??1class?http_client_base
??2{
??3public:
??4????http_client_base(boost::asio::io_service&?io_service)
??5????????:resolver_(io_service),socket_(io_service)
??6????{?
??7????}
??8????
??9????void?async_connect(const?std::string&?address,const?std::string&?port)
?10????{????
?11????????boost::asio::ip::tcp::resolver::query?query(address,?port);
?12????????resolver_.async_resolve(query,boost::bind(&http_client::handle_resolve,?this,
?13????????asio::placeholders::error,asio::placeholders::iterator));
?14????}
?15????
?16????void?async_write(const?void*?data,size_t?size,bool?in_place=false)
?17????{
?18????????if(!in_place){
?19????????????//do?something
?20????????????asio::async_write(socket_,request_,
?21????????????????????????????boost::bind(&http_client::handle_write,this,boost::asio::placeholders::error));
?22????????}else
?23????????????asio::async_write(socket_,asio::buffer(data,size),
?24????????????????????????????boost::bind(&http_client::handle_write,this,boost::asio::placeholders::error));
?25????}
?26????
?27????void?async_write_some(const?void*?data,size_t?size,bool?in_place=false)
?28????{
?29????????if(!in_place){
?30????????????//do?something
?31????????????boost::asio::async_write(socket_,request_,
?32????????????????????????????????????boost::bind(&http_client::handle_write_some,this,boost::asio::placeholders::error));
?33????????}else
?34????????????boost::asio::async_write(socket_,boost::asio::buffer(data,size),
?35????????????????????????????????????boost::bind(&http_client::handle_write_some,this,boost::asio::placeholders::error));
?36????}
?37
?38private:
?39????void?handle_resolve(const?boost::system::error_code&?e,boost::asio::ip::tcp::resolver::iterator?endpoint_iterator)
?40????{
?41????????if?(!e)
?42????????????boost::asio::async_connect(socket_,?endpoint_iterator,
?43????????????????????????????????????boost::bind(&http_client::handle_connect,this,boost::asio::placeholders::error));
?44????????else
?45????????????onIoError(e);
?46????}
?47????
?48????void?handle_connect(const?boost::system::error_code&?e)
?49????{
?50????????if(!e)
?51????????????onConnect();
?52????????else
?53????????????onIoError(e);
?54????}
?55
?56????void?handle_write_some(const?boost::system::error_code&?e)
?57????{
?58????????if(!e)
?59????????????onWriteSome();
?60????????else
?61????????????onIoError(e);
?62????}
?63
?64????void?handle_write(const?boost::system::error_code&?e)
?65????{
?66????????if(!e)
?67????????????boost::asio::async_read_until(socket_,?response_,"\r\n\r\n",
?68????????????????????????????boost::bind(&http_client::handle_read_header,this,
?69????????????????????????????boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
?70????????else
?71????????????onIoError(e);
?72????}
?73????
?74????void?handle_read_header(const?boost::system::error_code&?e,size_t?bytes_transferred)
?75????{
?76????????if(!e){
?77????????????//do?something
?78????????????boost::asio::async_read(socket_,response_,asio::transfer_at_least(1),
?79????????????????????????????boost::bind(&http_client::handle_read_content,this,
?80????????????????????????????boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred);????????????????????????????
?81????????}else
?82????????????onIoError(e);
?83????}
?84
?85????void?handle_read_content(const?boost::system::error_code&?e,size_t?bytes_transferred)
?86????{
?87????????if(!e){
?88????????????//do?something
?89????????????boost::asio::async_read(socket_,response_,asio::transfer_at_least(1),
?90????????????????????????????????boost::bind(&http_client::handle_read_content,this,
?91????????????????????????????????boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
?92????????}else
?93????????????onIoError(e);
?94????}
?95
?96protected:
?97????virtual?void?onConnect(){}
?98????virtual?void?onWriteSome(){}
?99????virtual?void?onIoError(const?boost::system::error_code&?e){}
100
101private:
102????boost::asio::ip::tcp::socket?socket_;
103????boost::asio::ip::tcp::resolver?resolver_;
104????boost::asio::streambuf?request_;
105????boost::asio::streambuf?response_;
106}; ???顯而易見,http_client_base使用tcp::socket作為底層實現,所以數據是非ssl傳輸的?,F因需求變更,為了數據安全要求使用ssl傳輸。但boost asio中的ssl::stream類接口和tcp::socket有所不同。其實在非ssl和ssl間,不同的只是讀寫數據的方法,而數據處理邏輯不變,因此為了重用http_client_base的機制框架和對http數據的解析,那么怎么使http_client_base不作大的改動就支持ssl呢?通過研究boost asio源碼發現,async_xxx系列自由函數內部要求讀寫流實現read_some、async_read_some、write_some和async_write_some4個短讀寫方法。由于tcp::socket已實現短讀寫而且ssl::stream是tcp::socket的上層,因此只要設計一個抽象的基類流,使之支持read_some、async_some_read、w rite _some和async_write_some即可,而實現使用dynamic_cast轉到兄弟基類tcp::socket或ssl::stream,再調用它們對應的同名短讀寫方法;另外還需要給出獲取最底層socket的接口,以支持async_connect和connect方法。因此針對這一設計實現,則要求派生類必須同時從抽象基類和其兄弟基類tcp::socket或ssl::stream繼承。
框架實現 ?
??1template<typename?T>
??2class?boost_socket_base
??3{
??4public:
??5????typedef?boost::asio::ssl::stream<T>?ssl_socket_base_t;
??6????typedef?T?socket_base_t;
??7
??8protected:
??9????boost_socket_base()
?10????????:tb_(boost::indeterminate)
?11????{
?12????}
?13
?14public:
?15????virtual?~boost_socket_base()?{}
?16
?17????ssl_socket_base_t*?get_ssl_socket()
?18????{
?19????????if(tb_){
?20????????????BOOST_ASSERT(ss_);????????
?21????????????return?ss_;
?22????????}else?if(!tb_)
?23????????????return?NULL;
?24????????else{
?25????????????if(ss_=dynamic_cast<ssl_socket_base_t*>(this))
?26????????????????tb_?=?true;
?27????????????return?ss_;
?28????????}?
?29????}
?30
?31????socket_base_t*?get_socket()
?32????{
?33????????if(!tb_){
?34????????????BOOST_ASSERT(s_);????????
?35????????????return?s_;
?36????????}else?if(tb_)
?37????????????return?NULL;
?38????????else{
?39????????????if(s_=dynamic_cast<socket_base_t*>(this))
?40????????????????tb_?=?false;
?41????????????return?s_;
?42????????}
?43????}
?44
?45????void?reset()
?46????{????tb_?=?boost::indeterminate;?}
?47
?48????typename?T::lowest_layer_type&?lowest_layer()
?49????{
?50????????ssl_socket_base_t*?p?=?get_ssl_socket();
?51????????if(p)?
?52????????????return?p->lowest_layer();
?53????????else
?54????????????return?get_socket()->lowest_layer();
?55????}
?56
?57????template?<typename?MutableBufferSequence>
?58????std::size_t?read_some(const?MutableBufferSequence&?buffers)
?59????{
?60????????ssl_socket_base_t*?p?=?get_ssl_socket();
?61????????if(p)?
?62????????????return?p->read_some(buffers);
?63????????else
?64????????????return?get_socket()->read_some(buffers);
?65????}
?66????
?67????template?<typename?MutableBufferSequence>
?68????std::size_t?read_some(const?MutableBufferSequence&?buffers,boost::system::error_code&?ec)
?69????{
?70????????ssl_socket_base_t*?p?=?get_ssl_socket();
?71????????if(p)?
?72????????????return?p->read_some(buffers,ec);
?73????????else
?74????????????return?get_socket()->read_some(buffers,ec);
?75????}
?76
?77????template?<typename?MutableBufferSequence,?typename?ReadHandler>
?78????void?async_read_some(const?MutableBufferSequence&?buffers,BOOST_ASIO_MOVE_ARG(ReadHandler)?handler)
?79????{
?80????????ssl_socket_base_t*?p?=?get_ssl_socket();
?81????????if(p)?
?82????????????return?p->async_read_some(buffers,handler);
?83????????else
?84????????????return?get_socket()->async_read_some(buffers,handler);
?85????}
?86
?87????template?<typename?ConstBufferSequence>
?88????std::size_t?write_some(const?ConstBufferSequence&?buffers,boost::system::error_code&?ec)
?89????{
?90????????ssl_socket_base_t*?p?=?get_ssl_socket();
?91????????if(p)?
?92????????????return?p->write_some(buffers,ec);
?93????????else
?94????????????return?get_socket()->write_some(buffers,ec);
?95????}
?96
?97????template?<typename?ConstBufferSequence>
?98????std::size_t?write_some(const?ConstBufferSequence&?buffers)
?99????{
100????????ssl_socket_base_t*?p?=?get_ssl_socket();
101????????if(p)?
102????????????return?p->write_some(buffers);
103????????else
104????????????return?get_socket()->write_some(buffers);
105????}
106
107????template?<typename?MutableBufferSequence,?typename?ReadHandler>
108????void?async_write_some(const?MutableBufferSequence&?buffers,BOOST_ASIO_MOVE_ARG(ReadHandler)?handler)
109????{????
110????????ssl_socket_base_t*?p?=?get_ssl_socket();
111????????if(p)?
112????????????return?p->async_write_some(buffers,handler);
113????????else
114????????????return?get_socket()->async_write_some(buffers,handler);
115????}
116
117private:
118????boost::tribool?tb_;
119????union?{
120????????ssl_socket_base_t*?ss_;
121????????socket_base_t*?s_;
122????};
123}; ???考慮到dynamic_cast轉換的性能開銷,因此增加了三態邏輯變量tb_和union指針,tb_表示當前this實際指向的對象類型,初始化為indeterminate,true表示ssl socket對象,使用ss_;false表示普通socket對象,使用s_。這樣一來,當且僅當tb_為indeterminate時才dynamic_cast。由于這點優化僅對基類指針操作有效,而對派生對象實無必要,所以tb_和union指針設為私有的;而且基類指針可以指向不同的子類對象,所以增加了reset方法重設tb_為indeterminate狀態,保證行為的正確性。
應用改進
???使用boost_socket_base框架后,只須5個地方稍作改動即可。
???1)成員變量 :由原來的boost::asio::ip::tcp改為boost_socket_base<boost_tcp_socket>*類型。 1typedef?boost::asio::ip::tcp::socket?boost_tcp_socket;
2boost_socket_base<boost_tcp_socket>*?socket_;
??? 2)構造函數 :增加boost::asio::ssl::context* ctx參數,默認為NULL,表示不使用ssl。
1http_client_base(boost::asio::io_service&?io_service,boost::asio::ssl::context*?ctx=NULL)
2????:resolver_(io_service)
3{
4????????if(ctx)
5????????????socket_?=?new?boost_ssl_socket<boost_tcp_socket>(io_service,*ctx);
6????????else
7????????????socket_?=?new?boost_socket<boost_tcp_socket>(io_service);
8}
??? 3)握手 處理 :與非ssl不同的是,在連接后需要進行握手,握手成功后才回調onConnect。
?1void?handle_connect(const?boost::system::error_code&?e)
?2{
?3????if(!e){
?4????????boost_socket_base<boost_tcp_socket>::ssl_socket_base_t*?p?=?socket_->get_ssl_socket();
?5????????if(p)
?6????????????p->async_handshake(boost::asio::ssl::stream_base::client,boost::bind(&http_client::handle_handshake,
?7???????????????????????????this,boost::asio::placeholders::error));
?8????????else
?9????????????onConnect();
10????}else
11????????onIoError(e);
12}
13void?handle_handshake(const?boost::system::error_code&?e)
14{
15????if(!e)
16????????onConnect();
17????else
18????????onIoError(e);
19}
??? 4)異步連接 :由于async_connect只接受boost::basic_socket類即最底層的socket作為參數,因此需要調用lowest_layer。
1void?handle_resolve(const?boost::system::error_code&?e,boost::asio::ip::tcp::resolver::iterator?endpoint_iterator)
2{
3????if?(!e)
4????????boost::asio::async_connect(socket_->lowest_layer(),?endpoint_iterator,boost::bind(&http_client::handle_connect,this,boost::asio::placeholders::error));
5????else
6????????onIoError(e);
7}
???5)async_xxx調用 :將參數socet_改為*socket_,例如下。
?1void?async_write(const?void*?data,size_t?size,bool?in_place=false)
?2{
?3????if(!in_place){
?4????????//do?something
?5????????boost::asio::async_write(*socket_,request_,boost::bind(&http_client::handle_write,this,boost::asio::placeholders::error));
?6????}else
?7????????boost::asio::async_write(*socket_,asio::buffer(data,size),boost::bind(&http_client::handle_write,this,boost::asio::placeholders::error));
?8}
?9void?handle_write(const?boost::system::error_code&?e)
10{
11????if(!e)
12????????boost::asio::async_read_until(*socket_,?response_,?"\r\n\r\n",
13????????????????????boost::bind(&http_client::handle_read_header,this,boost::asio::placeholders::error,asio::placeholders::bytes_transferred));
14????else
15????????onIoError(e);
16}
總結
以上是生活随笔為你收集整理的基于boost asio实现的支持ssl的通用socket框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MMKV_MMKV——1.使用
- 下一篇: linux下unix timestamp