します。https://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/examples/cpp11_examples.html考慮にブースト産業強さ、そのため直接使用する、公式のサンプルアドレスコードを撮影
より少ないコード、高い安定性、高速を使用することは非常に便利です。
その後、実際のプロセスは、クライアントの最初の開始などに接続生命維持機能を、切り離しサーバーにもクライアントアップサーバーアップ希望は、すぐに開始することを望んで。ネットワークの変動の場合、クライアントは、切断がアップ接続された直後に再び切断した可能性があります。
研究は、非同期接続は、成功した場合、それが成功しなかった、)(do_read_headerを行ったとき、あなたはdo_connectできることを見出した後に元のサンプルコードは、上記の二つの機能を達成することはできません
断線が発生した場合とis_connected_提供クラスの接続識別子は、接続IDがfalseに設定され、この外部識別子を検出し続けて、識別が偽発見され、クライアントが全体を再起動することができ
完全なコードの変更、あなたがダウンロードするWebサイトにテストサーバーの先頭に移動する必要があります。
// // chat_client.cpp // ~~~~~~~~~~~~~~~ // // 著作権(C)2003年から2013年クリストファー・M. Kohlhoff(クリスkohlhoffドットコムで) // // ブーストソフトウェアライセンス、バージョン1.0の下で配布されています。(参照ください //のファイルLICENSE_1_0.txtをまたはでコピーhttp://www.boost.org/LICENSE_1_0.txt ) // https://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/例/ cpp11_examples.html する#include <cstdlib> 書式#include <両端キュー> の#include <iostreamの> の#include <スレッド> の#include <ブースト/ asio.hpp> の#include "chat_message.hpp 「 使用して、ブースト:: ASIO :: IP :: TCP のtypedefのstd :: dequeの <chat_message> ; chat_message_queue クラスchat_client { パブリック: chat_clientを(向上:: ASIO :: io_service&io_service、 TCP ::リゾルバ::イテレータendpoint_iterator) :io_service_(io_service)、 socket_(io_service) { is_connected_ = 偽; do_connect(endpoint_iterator); } ボイドライト(CONST chat_message&MSG) { io_service_.post( [ この、MSG() { BOOL write_in_progress =!write_msgs_.empty(); write_msgs_.push_back(MSG)。 もし(!write_in_progress) { do_write(); } })。 } ボイド近い() { io_service_.post([ 本](){close_socket();}); } BOOL get_connected()のconst { 戻りis_connected_。 } プライベート: 無効(TCP ::レゾルバ::イテレータendpoint_iterator)do_connect { ブースト:: ASIO :: async_connect(socket_、endpoint_iterator、 [ この、endpoint_iterator](ブースト::システム:: ERROR_CODE EC、TCP ::リゾルバ::イテレータを) { 場合(!EC) { is_connected_ = 真; do_read_header(); } 他{ do_connect(endpoint_iterator); } })。 } ボイドdo_read_header() { ブースト:: ASIO :: async_read(socket_、 ブースト:: ASIO ::バッファ(read_msg_.data()、chat_message :: header_length)、 [ do_read_body()この(ブースト::システム:: ERROR_CODE EC、スタンダード:: size_tの/ * 長さ* / ) { 場合(EC &&!read_msg_.decode_header()) { do_read_body()。 } 他 { close_socket()。 } })。 } ボイドclose_socket() { socket_.close()。 is_connected_ = 偽; } ボイド { ブースト:: ASIO :: async_read(socket_、 ブースト:: ASIO ::バッファ(read_msg_.body()、read_msg_.body_length())、 [ これ ](ブースト::システム:: ERROR_CODE EC、スタンダード:: size_tの/ * 長さ* / ) { 場合(!EC) { STD :: cout.write(read_msg_.body()、read_msg_.body_length())。 std :: coutの << " \ nを" ; do_read_header(); } 他 { close_socket()。 } })。 } ボイド do_write() { ブースト:: ASIO :: async_write(socket_、 ブースト:: ASIOを::バッファ(write_msgs_.front()。データ()、 write_msgs_.front()。長さ())、 [ }これは(ブースト::システム:: ERROR_CODEをEC、STD :: size_t型/ * 長さ* / ) { 場合(!EC) { write_msgs_.pop_front(); もし!(write_msgs_.empty()) { do_write(); } } 他 { close_socket(); }); } プライベート): BOOL is_connected_。 :: ASIO :: io_service後押し&io_service_。 TCPソケット:: socket_。 chat_messageのread_msg_。 chat_message_queue write_msgs_; }。 INTメイン(int型 ARGC、CHAR * ARGV []) { 場合(!ARGC = 3 ) { のstd :: CERR << " 使い方:chat_client <ホスト>、<ポート>の\ n " 。 リターン 1 ; } 一方(真 { { しようと 後押し:: ASIO :: io_service io_service。 TCP ::リゾルバリゾルバ(io_service)。 オートendpoint_iterator = resolver.resolve({ARGV [ 1 ]、ARGV [ 2 ]})。 chat_clientのC(io_service、endpoint_iterator)。 STD ::スレッドT([&io_service](){io_service.run();}); // チャーライン[chat_message :: max_body_length + 1]。 // 一方(STD :: cin.getline(ライン、chat_message :: max_body_length + 1)) // { // chat_messageのMSG。 // msg.body_length(STD :: strlenを(ライン)); // はstd :: memcpyを(msg.body()、ライン、msg.body_length()); // msg.encode_header(); // c.write(MSG)。 // } しばらく(c.get_connected()) { のstd :: this_thread :: sleep_for(STD ::クロノ::ミリ秒(1 ))。 } c.close()。 t.join(); } キャッチ(スタンダード::例外&E) { のstd :: CERR << " 例外:"<< e.what()<< " の\ n " 。 } } 戻り 0 。 }