"Boost.Asio C ++ рдиреЗрдЯрд╡рд░реНрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧред" рдЕрдзреНрдпрд╛рдп 4: рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░

рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░!
рдореИрдВ рдЬреЙрди рдЯреЛрд░рдЬреЛ рдХреА рдкреБрд╕реНрддрдХ Boost.Asio C ++ рдиреЗрдЯрд╡рд░реНрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрддрд╛ рд╣реВрдВред

рд╕рд╛рдордЧреНрд░реА:


рдЗрд╕ рдЕрдзреНрдпрд╛рдп рдореЗрдВ, рд╣рдо Boost.Asio рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЧреИрд░-рддреБрдЪреНрдЫ рдХреНрд▓рд╛рдЗрдВрдЯ / рд╕рд░реНрд╡рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдПрдХ рдмрд╛рд░ рдЬрдм рдЖрдк рдЙрдиреНрд╣реЗрдВ рд╕рдордЭ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ:

рдЧреНрд░рд╛рд╣рдХ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрд░реЛрдз рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

рдордиреЛрд░рдВрдЬрди рдХреЗ рд▓рд┐рдП, рдХреБрдЫ рдЯреНрд░рд┐рдХреНрд╕ рдЬреЛрдбрд╝реЗрдВ:


рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕рд░реНрд╡рд░ / рдХреНрд▓рд╛рдЗрдВрдЯ


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдПрдХ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдХреЛрдб рд╕рд░рд▓ рдФрд░ рд╕реАрдЦрдиреЗ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдиреЗрдЯрд╡рд░реНрдХ рднрд╛рдЧ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рд╕рднреА рдиреЗрдЯрд╡рд░реНрдХ рдХреЙрд▓ рдЕрд╡рд░реБрджреНрдз рд╣реИрдВред

рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЧреНрд░рд╛рд╣рдХ

рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЧреНрд░рд╛рд╣рдХ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдХреА рдЙрдореНрдореАрдж рдереА, рд╕рдм рдХреБрдЫ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдХрд░рддрд╛ рд╣реИ; рд╕рд░реНрд╡рд░ рд╕реЗ рдЬреБрдбрд╝рддрд╛ рд╣реИ, рдЙрд╕ рдкрд░ рд▓реЙрдЧ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдПрдХ рд╕рдВрдЪрд╛рд░ рдЪрдХреНрд░ рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреН рд╕реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рдПрдХ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ, рд╕рд░реНрд╡рд░ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкрдврд╝рддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╕реЗ рд╕реЛ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реА рддрд░рд╣ред



рдЪреВрдВрдХрд┐ рд╣рдо рдПрдХ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрд╕реНрдХрд░рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдпрд╣ рд╣рдореЗрдВ рдХреБрдЫ рдЪреАрдЬреЛрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рд░реНрд╡рд░ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ; рдЪрд▓реЛ рдЗрд╕реЗ рдПрдХ рд▓реВрдк рдореЗрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣:

 ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 8001); void run_client(const std::string & client_name) { talk_to_svr client(client_name); try { client.connect(ep); client.loop(); } catch(boost::system::system_error & err) { std::cout << "client terminated " << std::endl; } } 

рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдг talk_to_svr рд╡рд░реНрдЧ рд╣реИ:

 struct talk_to_svr { talk_to_svr(const std::string & username): sock_(service), started_(true), username_(username) {} void connect(ip::tcp::endpoint ep) { sock_.connect(ep); } void loop() { write("login " + username_ + "\n"); read_answer(); while ( started_) { write_request(); read_answer(); boost::this_thread::sleep(millisec(rand() % 7000)); } } std::string username() const { return username_; } ... private: ip::tcp::socket sock_; enum { max_msg = 1024 }; int already_read_; char buff_[max_msg]; bool started_; std::string username_; }; 

рд▓реВрдк рдореЗрдВ, рд╣рдо рд╕рд┐рд░реНрдл рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддреЗ рд╣реИрдВ, рд╕рд░реНрд╡рд░ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкрдврд╝рддреЗ рд╣реИрдВ рдФрд░ рд╕реЛ рдЬрд╛рддреЗ рд╣реИрдВред рд╣рдо рдЕрдирд┐рд╢реНрдЪрд┐рдд рд╕рдордп рдХреЗ рд▓рд┐рдП рд╕реЛ рдЬрд╛рддреЗ рд╣реИрдВ (рдХрднреА-рдХрднреА 5 рд╕реЗрдХрдВрдб рд╕реЗ рдЕрдзрд┐рдХ), рдЗрд╕рд▓рд┐рдП рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░ рд╕рд░реНрд╡рд░ рд╣рдореЗрдВ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛:

 void write_request() { write("ping\n"); } void read_answer() { already_read_ = 0; read(sock_, buffer(buff_), boost::bind(&talk_to_svr::read_complete, this, _1, _2)); process_msg(); } void process_msg() { std::string msg(buff_, already_read_); if ( msg.find("login ") == 0) on_login(); else if ( msg.find("ping") == 0) on_ping(msg); else if ( msg.find("clients ") == 0) on_clients(msg); else std::cerr << "invalid msg " << msg << std::endl; } 

рдЙрддреНрддрд░ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП read_complete (рдЬрд┐рд╕рдХрд╛ рдкрд┐рдЫрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рдмрд╣реБрдд рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЪрд░рд┐рддреНрд░ '\ n' рддрдХ рдкрдврд╝рддреЗ рд╣реИрдВред рддрд░реНрдХ process_msg() рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ, рдЬрд╣рд╛рдВ рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкрдврд╝рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд╕рд╣реА рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

 void on_login() { do_ask_clients(); } void on_ping(const std::string & msg) { std::istringstream in(msg); std::string answer; in >> answer >> answer; if ( answer == "client_list_changed") do_ask_clients(); } void on_clients(const std::string & msg) { std::string clients = msg.substr(8); std::cout << username_ << ", new client list:" << clients; } void do_ask_clients() { write("ask_clients\n"); read_answer(); } void write(const std::string & msg) { sock_.write_some(buffer(msg)); } size_t read_complete(const boost::system::error_code & err, size_t bytes) { // ... same as before } 

рд╣рдорд╛рд░реЗ рдкрд┐рдВрдЧ рдореЗрдВ рд╕рд░реНрд╡рд░ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛ рдкрдврд╝рдиреЗ рдкрд░, рдЕрдЧрд░ рд╣рдореЗрдВ client_list_changed рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдлрд┐рд░ рд╕реЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВред

рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕рд░реНрд╡рд░

рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕рд░реНрд╡рд░ рднреА рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред рдЗрд╕реЗ рджреЛ рдзрд╛рдЧреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдПрдХ рдирдП рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рд╕реБрдирдиреЗ рдХреЗ рд▓рд┐рдП, рджреВрд╕рд░рд╛ рдореМрдЬреВрджрд╛ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдПред рдпрд╣ рдПрдХ рдереНрд░реЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рдирдП рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдирд╛ рдПрдХ рдЕрд╡рд░реБрджреНрдз рдСрдкрд░реЗрд╢рди рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдореМрдЬреВрджрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдереНрд░реЗрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред



рдЬреИрд╕рд╛ рдХрд┐ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛, рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд┐рдЦрдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╕рд░реНрд╡рд░ рд▓рд┐рдЦрдирд╛ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдПрдХ рдУрд░, рдпрд╣ рд╕рднреА рдЬреБрдбрд╝реЗ рд╣реБрдП рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЪреВрдВрдХрд┐ рд╣рдо рд╕рд░реНрд╡рд░ рдХрд╛ рдПрдХ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рдВрд╕реНрдХрд░рдг рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рд╣рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рджреЛ рдереНрд░реЗрдбреНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рдирдП рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ (рдХреНрдпреЛрдВрдХрд┐ accept() рдЕрд╡рд░реБрджреНрдз рдСрдкрд░реЗрд╢рди рд╣реИ), рдФрд░ рджреВрд╕рд░рд╛ рдореМрдЬреВрджрд╛ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ:

 void accept_thread() { ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(), 8001)); while ( true) { client_ptr new_( new talk_to_client); acceptor.accept(new_->sock()); boost::recursive_mutex::scoped_lock lk(cs); clients.push_back(new_); } } void handle_clients_thread() { while ( true) { boost::this_thread::sleep( millisec(1)); boost::recursive_mutex::scoped_lock lk(cs); for(array::iterator b = clients.begin(),e = clients.end(); b != e; ++b) (*b)->answer_to_client(); // erase clients that timed out clients.erase(std::remove_if(clients.begin(), clients.end(), boost::bind(&talk_to_client::timed_out,_1)), clients.end()); } } int main(int argc, char* argv[]) { boost::thread_group threads; threads.create_thread(accept_thread); threads.create_thread(handle_clients_thread); threads.join_all(); } 

рд╣рдореЗрдВ рдЙрдирд╕реЗ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
talk_to_client рдкреНрд░рддреНрдпреЗрдХ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдПрдХ рд╕реЙрдХреЗрдЯ рд╣реИред рдЗрд╕рдореЗрдВ рдПрдХ рдХреЙрдкреА рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рдЗрд╕реЗ std::vector рдореЗрдВ рд░рдЯрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЗрд╕ рдкрд░ рдПрдХ рд╕рд╛рдЭрд╛ рдкреЙрдЗрдВрдЯрд░ рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рджреЛ рддрд░реАрдХреЗ рд╣реИрдВ: рдпрд╛ рддреЛ talk_to_client рдЕрдВрджрд░ рд╕реЙрдХреЗрдЯ рдкрд░ рдПрдХ рд╕рд╛рдЭрд╛ рдкреЙрдЗрдВрдЯрд░ рдорд┐рд▓рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ talk_to_client рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреА рдПрдХ рд╕рд░рдгреА рдмрдирд╛рддреЗ рд╣реИрдВ рдпрд╛ рдЬрдм рдПрдХ рд╕реЙрдХреЗрдЯ рдХреЗ рд╕рд╛рде рдПрдХ talk_to_client рдЙрджрд╛рд╣рд░рдг рд╣реЛрддрд╛ рд╣реИ рдФрд░ Talk_to_client рдкрд░ рд╕рд╛рдЭрд╛ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреА рдПрдХ рд╕рд░рдгреА рдбрд╛рд▓рддреЗ рд╣реИрдВред рдореИрдВрдиреЗ рдмрд╛рдж рдХреЛ рдЪреБрдирд╛, рд▓реЗрдХрд┐рди рдЖрдк рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рд╕реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ:

 typedef boost::shared_ptr<talk_to_client> client_ptr; typedef std::vector<client_ptr> array; array clients; boost::recursive_mutex cs; // thread-safe access to clients array 

рдореБрдЦреНрдп talk_to_client рдХреЛрдб рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:

 struct talk_to_client : boost::enable_shared_from_this<talk_to_client> { talk_to_client() { ... } std::string username() const { return username_; } void answer_to_client() { try { read_request(); process_request(); } catch ( boost::system::system_error&) { stop(); } if ( timed_out()) stop(); } void set_clients_changed() { clients_changed_ = true; } ip::tcp::socket & sock() { return sock_; } bool timed_out() const { ptime now = microsec_clock::local_time(); long long ms = (now - last_ping).total_milliseconds(); return ms > 5000 ; } void stop() { boost::system::error_code err; sock_.close(err); } void read_request() { if ( sock_.available()) already_read_ += sock_.read_some( buffer(buff_ + already_read_, max_msg - already_read_)); } ... private: // ... same as in Synchronous Client bool clients_changed_; ptime last_ping; }; 

рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд╣реИред рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХрд╛рд░реНрдп read_request() ред рдбреЗрдЯрд╛ рд╣реЛрдиреЗ рдкрд░ рд╣реА рд░реАрдбрд┐рдВрдЧ рд╣реЛрдЧреА, рдЗрд╕рд▓рд┐рдП рд╕рд░реНрд╡рд░ рдХрднреА рдмреНрд▓реЙрдХ рдирд╣реАрдВ рд╣реЛрдЧрд╛:

 void process_request() { bool found_enter = std::find(buff_, buff_ + already_read_, '\n') < buff_ + already_read_; if ( !found_enter) return; // message is not full // process the msg last_ping = microsec_clock::local_time(); size_t pos = std::find(buff_, buff_ + already_read_, '\n') - buff_; std::string msg(buff_, pos); std::copy(buff_ + already_read_, buff_ + max_msg, buff_); already_read_ -= pos + 1; if ( msg.find("login ") == 0) on_login(msg); else if ( msg.find("ping") == 0) on_ping(); else if ( msg.find("ask_clients") == 0) on_clients(); else std::cerr << "invalid msg " << msg << std::endl; } void on_login(const std::string & msg) { std::istringstream in(msg); in >> username_ >> username_; write("login ok\n"); update_clients_changed(); } void on_ping() { write(clients_changed_ ? "ping client_list_changed\n" : "ping ok\n"); clients_changed_ = false; } void on_clients() { std::string msg; { boost::recursive_mutex::scoped_lock lk(cs); for( array::const_iterator b = clients.begin(), e = clients.end() ;b != e; ++b) msg += (*b)->username() + " "; } write("clients " + msg + "\n"); } void write(const std::string & msg) { sock_.write_some(buffer(msg)); } 

process_request() рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред рдЬрдм рд╣рдо рдЙрдкрд▓рдмреНрдз рдбреЗрдЯрд╛ рдХреЛ рдкрдврд╝рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреНрдпрд╛ рд╣рдо рд╕рдВрджреЗрд╢ рдХреЛ рдЕрдВрдд рддрдХ found_enteris (рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ found_enteris рдХреЛ рд╕рд╣реА рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ found_enteris )ред рдпрджрд┐ рдпрд╣ рдорд╛рдорд▓рд╛ рд╣реИ, рддреЛ рд╣рдо рдЦреБрдж рдХреЛ рдкрдврд╝рдиреЗ рд╕реЗ рдмрдЪрд╛рддреЗ рд╣реИрдВ, рд╢рд╛рдпрдж рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрджреЗрд╢ ('n' рд╡рд░реНрдг рдХреЗ рдмрд╛рдж рдмрдлрд░ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрдЪрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛), рдФрд░ рдлрд┐рд░ рд╣рдо рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрдврд╝реЗ рдЧрдП рд╕рдВрджреЗрд╢ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рддреЗ рд╣реИрдВред рдмрд╛рдХреА рдХреЛрдб рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред

рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рд░реНрд╡рд░ / рдХреНрд▓рд╛рдЗрдВрдЯ


рдФрд░ рдЕрдм рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк (рдФрд░ рдХрдард┐рди) рднрд╛рдЧ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдЪрд▓рддреЗ рд╣реИрдВред

рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЧреНрд░рд╛рд╣рдХ

рдЪреАрдЬреЛрдВ рдХреЛ рдЕрдм рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдорд╛рдирд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рдмрдВрдзрдиреАрдпред рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реЛрдЧрд╛ рдЬреЛ рдмреНрд▓реЙрдХ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред



рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирд┐рдореНрди рдХреЛрдб рдХреЛ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рд┐рдП:

 #define MEM_FN(x) boost::bind(&self_type::x, shared_from_this()) #define MEM_FN1(x,y) boost::bind(&self_type::x, shared_from_this(),y) #define MEM_FN2(x,y,z) boost::bind(&self_type::x, shared_from_this(),y,z) class talk_to_svr : public boost::enable_shared_from_this<talk_to_svr>, boost::noncopyable { typedef talk_to_svr self_type; talk_to_svr(const std::string & username) : sock_(service), started_(true), username_(username), timer_(service) {} void start(ip::tcp::endpoint ep) { sock_.async_connect(ep, MEM_FN1(on_connect,_1)); } public: typedef boost::system::error_code error_code; typedef boost::shared_ptr<talk_to_svr> ptr; static ptr start(ip::tcp::endpoint ep, const std::string & username) { ptr new_(new talk_to_svr(username)); new_->start(ep); return new_; } void stop() { if ( !started_) return; started_ = false; sock_.close(); } bool started() { return started_; } ... private: size_t read_complete(const boost::system::error_code & err, size_t bytes) { if ( err) return 0; bool found = std::find(read_buffer_, read_buffer_ + bytes, '\n') < read_buffer_ + bytes; return found ? 0 : 1; } private: ip::tcp::socket sock_; enum { max_msg = 1024 }; char read_buffer_[max_msg]; char write_buffer_[max_msg]; bool started_; std::string username_; deadline_timer timer_; }; 

рдЖрдкрдХреЛ рд╕рд░реНрд╡рд░ рдХреЛ рдкрд┐рдВрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд deadline_timer рд╕реАрдорд╛_рдЯрд╛рдЗрдорд░ рдЯрд╛рдЗрдорд░ рдлрд╝рдВрдХреНрд╢рди рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛; рдФрд░ рдлрд┐рд░, рд╣рдо рд╕рдордп рдкрд░ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдмрд┐рдВрджреБ рдкрд░ рд╕рд░реНрд╡рд░ рдХреЗ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗред
рдЦреИрд░, рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХрдХреНрд╖рд╛ рдХрд╛ рдореБрдЦреНрдп рддрд░реНрдХ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:

 void on_connect(const error_code & err) { if ( !err) do_write("login " + username_ + "\n"); else stop(); } void on_read(const error_code & err, size_t bytes) { if ( err) stop(); if ( !started() ) return; // process the msg std::string msg(read_buffer_, bytes); if ( msg.find("login ") == 0) on_login(); else if ( msg.find("ping") == 0) on_ping(msg); else if ( msg.find("clients ") == 0) on_clients(msg); } void on_login() { do_ask_clients(); } void on_ping(const std::string & msg) { std::istringstream in(msg); std::string answer; in >> answer >> answer; if ( answer == "client_list_changed") do_ask_clients(); else postpone_ping(); } void on_clients(const std::string & msg) { std::string clients = msg.substr(8); std::cout << username_ << ", new client list:" << clients ; postpone_ping(); } 

on_read() рдореЗрдВ рдХреЛрдб рдХреА рдкрд╣рд▓реА рджреЛ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рдЦреВрдмрд╕реВрд░рддреА рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдореЗрдВ рд╣рдо рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реИ, рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд░реБрдХреЗрдВред рджреВрд╕рд░реА рдкрдВрдХреНрддрд┐ рдореЗрдВ рд╣рдо рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдо (рдЙрд╕рд╕реЗ рдкрд╣рд▓реЗ рдпрд╛ рдмрд╕) рд░реБрдХ рдЧрдП, рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд╣рдо рд╡рд╛рдкрд╕ рд▓реМрдЯрддреЗ рд╣реИрдВред рдЕрдиреНрдпрдерд╛, рдпрджрд┐ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рддреЛ рд╣рдо рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╕рдВрджреЗрд╢ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рдЕрдВрдд рдореЗрдВ, do_* рдлрд╝рдВрдХреНрд╢рди рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИрдВ:

 void do_ping() { do_write("ping\n"); } void postpone_ping() { timer_.expires_from_now(boost::posix_time::millisec(rand() % 7000)); timer_.async_wait( MEM_FN(do_ping)); } void do_ask_clients() { do_write("ask_clients\n"); } void on_write(const error_code & err, size_t bytes) { do_read(); } void do_read() { async_read(sock_, buffer(read_buffer_), MEM_FN2(read_complete,_1,_2), MEM_FN2(on_read,_1,_2)); } void do_write(const std::string & msg) { if ( !started() ) return; std::copy(msg.begin(), msg.end(), write_buffer_); sock_.async_write_some( buffer(write_buffer_, msg.size()), MEM_FN2(on_write,_1,_2)); } 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ read рдСрдкрд░реЗрд╢рди рдкрд┐рдВрдЧ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ:


рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рд░реНрд╡рд░

рдпрд╣ рдпреЛрдЬрдирд╛ рдХрд╛рдлреА рдЬрдЯрд┐рд▓ рд╣реИ, рдЖрдк рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЪрд╛рд░ рддреАрд░ Boost.Asio рд╕реЗ on_accept, on_read, on_write рдФрд░ on_check_ping рд╕реЗ рджреВрд░ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдореВрд▓ рд░реВрдк рд╕реЗ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЖрдк рдХрднреА рднреА рдХреЙрд▓ рд╕реЗ рдирд╣реАрдВ рдкрд╣рдЪрд╛рди рдкрд╛рдПрдВрдЧреЗ рдХрд┐ рдЗрди рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рдиреЛрдВ рдореЗрдВ рд╕реЗ рдХреМрди рд╕рд╛ рд╕рдм рдХреБрдЫ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдЖрдк рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рд╣реЛрдЧрд╛ред



рдЗрд╕рд▓рд┐рдП, рд╣рдо рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдПрдХ рдзрд╛рдЧреЗ рдореЗрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЯреБрдХрдбрд╝рд╛ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(), 8001)); void handle_accept(talk_to_client::ptr client, const error_code & err) { client->start(); talk_to_client::ptr new_client = talk_to_client::new_(); acceptor.async_accept(new_client->sock(), boost::bind(handle_accept,new_client,_1)); } int main(int argc, char* argv[]) { talk_to_client::ptr client = talk_to_client::new_(); acceptor.async_accept(client->sock(), boost::bind(handle_accept,client,_1)); service.run(); } 

рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рд╣рдореЗрд╢рд╛ рдирдП рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдЧрд╛ (рдкреНрд░рддреНрдпреЗрдХ рдирдпрд╛ рдЧреНрд░рд╛рд╣рдХ рдХрдиреЗрдХреНрд╢рди рдПрдХ рдФрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд╛ рдХрд╛рд░рдг рдмрдиреЗрдЧрд╛)ред
рд╣рдореЗрдВ client list changed рдШрдЯрдирд╛ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП (рдПрдХ рдирдпрд╛ рдЧреНрд░рд╛рд╣рдХ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ рдпрд╛ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдФрд░ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдФрд░ рдРрд╕рд╛ рд╣реЛрдиреЗ рдкрд░ рдЕрдиреНрдп рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░реЗрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдореЗрдВ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЕрдиреНрдпрдерд╛ рдЗрд╕ рд╕рд░рдгреА рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА рдирд┐рд╢реНрдЪрд┐рдд рд╕рдордп рдореЗрдВ рд╕рднреА рдЬреБрдбрд╝реЗ рд╣реБрдП рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рдЬрд╛рдирдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣реЗрдВрдЧреЗ:

 class talk_to_client; typedef boost::shared_ptr<talk_to_client> client_ptr; typedef std::vector<client_ptr> array; array clients; 

connection рд╡рд░реНрдЧ рдХрд╛ рдХрдВрдХрд╛рд▓ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:

 class talk_to_client : public boost::enable_shared_from_this<talk_to_ client>, boost::noncopyable { talk_to_client() { ... } public: typedef boost::system::error_code error_code; typedef boost::shared_ptr<talk_to_client> ptr; void start() { started_ = true; clients.push_back( shared_from_this()); last_ping = boost::posix_time::microsec_clock::local_time(); do_read(); // first, we wait for client to login } static ptr new_() { ptr new_(new talk_to_client); return new_; } void stop() { if ( !started_) return; started_ = false; sock_.close(); ptr self = shared_from_this(); array::iterator it = std::find(clients.begin(), clients.end(), self); clients.erase(it); update_clients_changed(); } bool started() const { return started_; } ip::tcp::socket & sock() { return sock_;} std::string username() const { return username_; } void set_clients_changed() { clients_changed_ = true; } ... private: ip::tcp::socket sock_; enum { max_msg = 1024 }; char read_buffer_[max_msg]; char write_buffer_[max_msg]; bool started_; std::string username_; deadline_timer timer_; boost::posix_time::ptime last_ping; bool clients_changed_; }; 

рдореИрдВ connection рд╡рд░реНрдЧ рд╕реЗ talk_to_client рдпрд╛ talk_to_server рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ talk_to_client рдЬреЛ рдореИрдВ рдХрд╣ рд░рд╣рд╛ рд╣реВрдВ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
рдЕрдм рд╣рдореЗрдВ рдкрд┐рдЫрд▓реЗ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛; рдпрд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рдХреЗ рд╕рдорд╛рди рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд stop() рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд░рдгреА рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд┐рдП рдЧрдП рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИред
рд╕рд░реНрд╡рд░ рд▓рдЧрд╛рддрд╛рд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкрдврд╝рдиреЗ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ:

 void on_read(const error_code & err, size_t bytes) { if ( err) stop(); if ( !started() ) return; std::string msg(read_buffer_, bytes); if ( msg.find("login ") == 0) on_login(msg); else if ( msg.find("ping") == 0) on_ping(); else if ( msg.find("ask_clients") == 0) on_clients(); } void on_login(const std::string & msg) { std::istringstream in(msg); in >> username_ >> username_; do_write("login ok\n"); update_clients_changed(); } void on_ping() { do_write(clients_changed_ ? "ping client_list_changed\n" : "ping ok\n"); clients_changed_ = false; } void on_clients() { std::string msg; for(array::const_iterator b =clients.begin(),e =clients.end(); b != e; ++b) msg += (*b)->username() + " "; do_write("clients " + msg + "\n"); } 

рдХреЛрдб рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ; рдПрдХ рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рдХреЛрдИ рдирдпрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рд▓реЙрдЧ рдЗрди рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдо update_clients_changed() рдХреЙрд▓ update_clients_changed() , рдЬреЛ рд╕рднреА рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд▓рд┐рдП clients_changed_ рдХреЛ true рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред
рдЬреИрд╕реЗ рд╣реА рдЙрд╕реЗ рдХреЛрдИ рдЕрдиреБрд░реЛрдз рдорд┐рд▓рддрд╛ рд╣реИ, рд╡рд╣ рддреБрд░рдВрдд рдЗрд╕рдХрд╛ рдЙрддреНрддрд░ рджреЗрддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЯреБрдХрдбрд╝рд╛ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:

 void do_ping() { do_write("ping\n"); } void do_ask_clients() { do_write("ask_clients\n"); } void on_write(const error_code & err, size_t bytes) { do_read(); } void do_read() { async_read(sock_, buffer(read_buffer_), MEM_FN2(read_complete,_1,_2), MEM_FN2(on_read,_1,_2)); post_check_ping(); } void do_write(const std::string & msg) { if ( !started() ) return; std::copy(msg.begin(), msg.end(), write_buffer_); sock_.async_write_some( buffer(write_buffer_, msg.size()), MEM_FN2(on_write,_1,_2)); } size_t read_complete(const boost::system::error_code & err, size_t bytes) { // ... as before } 

рдкреНрд░рддреНрдпреЗрдХ рд▓рд┐рдЦрдиреЗ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдЕрдВрдд рдореЗрдВ, on_write() рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рдФрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реАрдб рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕ рддрд░рд╣ рдПрдХ рдЕрдиреБрд░реЛрдз рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ - рдЗрд╕рдХрд╛ рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИ, рдЪрдХреНрд░ рддрдм рддрдХ рдЬрд╛рд░реА рд░рд╣рддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдЧреНрд░рд╛рд╣рдХ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдпрд╛ рдЯрд╛рдЗрдорд░ рдмрдВрдж рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ред
рдЪреВрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд░реАрдбрд┐рдВрдЧ 5 рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ, рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рдЯрд╛рдЗрдорд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд╣рдо рдХрдиреЗрдХреНрд╢рди рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВ:

 void on_check_ping() { ptime now = microsec_clock::local_time(); if ( (now - last_ping).total_milliseconds() > 5000) stop(); last_ping = boost::posix_time::microsec_clock::local_time(); } void post_check_ping() { timer_.expires_from_now(boost::posix_time::millisec(5000)); timer_.async_wait( MEM_FN(on_check_ping)); } 

рд╡рд╣ рдкреВрд░рд╛ рд╕рд░реНрд╡рд░ рд╣реИред рдЖрдк рдЗрд╕реЗ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ!

рд╕рд╛рд░рд╛рдВрд╢


рдЗрд╕ рдЕрдзреНрдпрд╛рдп рдореЗрдВ, рд╣рдордиреЗ рдХреБрдЫ рдмреБрдирд┐рдпрд╛рджреА рдХреНрд▓рд╛рдЗрдВрдЯ / рд╕рд░реНрд╡рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рджреЗрдЦрд╛ред рд╣рдо рд╕реНрдореГрддрд┐ рд▓реАрдХ рдФрд░ рдЧрддрд┐рд░реЛрдз рдЬреИрд╕реЗ рдЬрд╛рд▓ рд╕реЗ рдмрдЪ рдЧрдПред рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд░рдо рдЖрдкрдХреЗ рднрд╡рд┐рд╖реНрдп рдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреБрдХреНрдд рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдФрд░ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЕрдЧрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ, рд╣рдо Boost.Asio рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдмрдирд╛рдо рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ, рдЕрдВрддрд░ рдХреА рдЧрд╣рд░реА рд╕рдордЭ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ; рджреЗрдЦреЗрдВ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рди рдХреЛ рдХреИрд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рд╕рдВрд╕рд╛рдзрди: рд▓рд┐рдВрдХ

рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рд╕рднреА рдХрд╛ рдзрдиреНрдпрд╡рд╛рдж, рдЬрд▓реНрдж рд╣реА рдорд┐рд▓рддреЗ рд╣реИрдВ!

Source: https://habr.com/ru/post/In195794/


All Articles