The code is not available on the author's GitHub
Tap the code in the book to VC and debug the Run
Client.cpp: Defines the entry point of the console application. #include "stdafx.h" #include <boost/thread.hpp> #include <thread> #include <string> #include ". /common/rwhandler.h "Class Connector{public:connector (io_service& iOS, const string& strIp, short port): M_ios ( iOS), M_socket (iOS), m_serveraddr (Tcp::endpoint (address::from_string (strIp), port), m_isconnected (false), m_ Chkthread (nullptr) {Createeventhandler (iOS);} ~connector () {}bool Start () {M_eventhandler->getsocket (). Async_connect (M_SERVERADDR, [this] (const Boost::system: :error_code& error) {if (error) {Handleconnecterror (error); return;} cout << "Connect OK" << endl;m_isconnected = True;m_eventhandler->handleread ();}); Boost::this_thread::sleep (boost::p osix_time::seconds (1)); return m_isconnected;} BOOL IsConnected () Const{return m_isconnected;} void Send (char* data, int len) {if (!m_isconnected) return;m_eventhandler->handlewrite (Data,len);} void Asyncsend (char* data, int len) {if (!m_isconnected) Return;//m_eventhandler->hanDleasyncwrite (data, Len); M_eventhandler->handlewrite (data, Len);} Private:void Createeventhandler (io_service& ios) {M_eventhandler = std::make_shared<rwhandler> (iOS); m_ Eventhandler->setcallbackerror ([this] (int connid) {handlerwerror (Connid);});} void Checkconnect () {if (M_chkthread! = nullptr) Return;m_chkthread = std::make_shared<std::thread> ([this]{while (true) {if (! IsConnected ()) Start (); Boost::this_thread::sleep (boost::p osix_time::seconds (1));});} void Handleconnecterror (const boost::system::error_code& error) {m_isconnected = False;cout << error.message () << endl;m_eventhandler->closesocket (); Checkconnect ();} void Handlerwerror (int connid) {m_isconnected = false; Checkconnect ();} private:io_service& m_ios;tcp::socket m_socket;tcp::endpoint m_serveraddr;std::shared_ptr<rwhandler> m_ Eventhandler;bool m_isconnected;std::shared_ptr<std::thread> M_chkthread;}; int main () {Io_service ios;boost::asio::io_service::work work (iOS); boost::threadTHD ([&ios] {ios.run ();}); Connector Conn (iOS, "127.0.0.1", 9900); Conn. Start (); std::string str;if (!conn. IsConnected ()) {cin >> str;return-1;} const int len = 512;char Line[len] = "" while (Cin >> str) {char Header[head_len] = {};int Totallen = str.length () + 1 + head_len;std::sprintf (header, "%d", Totallen), memcpy (line, header, Head_len), memcpy (line + Head_len, Str.c_str (), Str.length () + 1); Conn. Send (line, Totallen);} return 0;}
Server.cpp: Defines the entry point of the console application. #include "stdafx.h" #include ". /common/rwhandler.h "#include". /common/message.h "#include <boost/asio/buffer.hpp> #include <unordered_map> #include <numeric> const int maxconnectionnum = 65536;const int maxrecvsize = 65536;class Server {public:server (io_service& iOS, Short po RT): M_ios (iOS), M_acceptor (iOS, Tcp::endpoint (TCP::V4 (), port)), M_connidpool (maxconnectionnum) {m_ Connidpool.resize (Maxconnectionnum); Std::iota (M_connidpool.begin (), M_connidpool.end (), 1);} ~server () {}void Accept () {cout << "Start listening" << endl;std::shared_ptr<rwhandler> handler = Createhandler (); M_acceptor.async_accept (Handler->getsocket (), [this, handler] (const BOOST::SYSTEM::ERROR_CODE & error) {if (error) {cout << error.value () << "" << error.message () << Endl; Handleacperror (handler, error); return;} M_handlers.insert (Std::make_pair (Handler->getconnid (), handler)) cout << "Current Connect count:" << M_handlers.size () << endl;handler->handleread (); Accept ();});} Private:void Handleacperror (std::shared_ptr<rwhandler> eventHandler, const boost::system::error_code& Error) {cout << error,error reason: "<< error.value () << error.message () << endl;eventhandler-& Gt Closesocket (); Stopaccept ();} void Stopaccept () {Boost::system::error_code ec;m_acceptor.cancel (EC); M_acceptor.close (EC); M_ios.stop ();} Std::shared_ptr<rwhandler> Createhandler () {int connid = M_connidpool.front (); M_connidpool.pop_front (); STD:: shared_ptr<rwhandler> handler = std::make_shared<rwhandler> (M_ios); Handler->setconnid (connId); Handler->setcallbackerror ([this] (int connid) {Recyclconnid (Connid);}); return handler;} void Recyclconnid (int connid) {Auto it = M_handlers.find (Connid); if (it = M_handlers.end ()) m_handlers.erase (it);//== cout << "Current Connect count:" << m_handlers.size () << endl;m_connidpool.push_back (Connid);} Private:io_service&amP M_ios;tcp::acceptor M_acceptor;std::unordered_map<int, std::shared_ptr<rwhandler>> m_handlers;list <int> M_connidpool;}; int main () {Io_service iOS; Server server (iOS, 9900); Accept (); Ios.run (); return 0;}
#pragma onceclass Message {public:enum {header_length = 4};enum {max_body_length = 512}; Message (): body_length_ (0) {}const char* data () const {return data_;} char* data () {return data_;} size_t Length () const {return header_length + body_length_;} Const char* Body () const {return data_ + header_length;} Char* body () {return data_ + header_length;} size_t body_length () const {return body_length_;} void Body_length (size_t new_length) {body_length_ = New_length;if (Body_length_ > Max_body_length) body_length_ = Max_ Body_length;} BOOL Decode_header () {char header[header_length + 1] = ""; Std::strncat (header, Data_, header_length); body_length_ = std:: Atoi (header)-header_length;if (Body_length_ > Max_body_length) {body_length_ = 0;return false;} return true;} void Encode_header () {char header[header_length + 1] = ""; std::sprintf (header, "%4d", body_length_); std::memcpy (Data_, Header,header_length);} Private:char data_[header_length + max_body_length];std::size_t body_length_;};
#pragma once#include <array> #include <functional> #include <iostream>using namespace std; #include <boost/asio.hpp>using namespace boost::asio;using namespace boost::asio::ip;using namespace Boost;const int MAX_ ip_pack_size = 65536;const int Head_len = 4;class Rwhandler {public:rwhandler (io_service& iOS): M_sock (iOS) {}~RWHand Ler () {}void handleread () {async_read (m_sock, buffer (m_buff), Transfer_at_least (Head_len), [this] (const BOOST::SYSTEM ::error_code& ec,size_t size) {if (ec! = nullptr) {HandleError (EC); return;} cout << m_buff.data () + Head_len << Endl; Handleread ();});} void Handlewrite (char* data, int len) {Boost::system::error_code ec;write (m_sock, buffer (data, Len), EC); if (ec! = nullptr ) HandleError (EC);} tcp::socket& Getsocket () {return m_sock;} void Closesocket () {Boost::system::error_code Ec;m_sock.shutdown (tcp::socket::shutdown_send, EC); M_sock.close (EC);} void Setconnid (int connid) {M_connid = Connid;} int Getconnid () const {return M_cOnnid; }template<typename f>void Setcallbackerror (f f) {m_callbackerror = f;} Private:void HandleError (const boost::system::error_code& EC) {closesocket (); cout << ec.message () << Endl;if (M_callbackerror) m_callbackerror (M_connid);} Private:tcp::socket M_sock;std::array<char, max_ip_pack_size> m_buff;int m_connid;std::function<void (int) > m_callbackerror;};
In-depth application c++11 with book code