コードを切断し、再接続するサンプルコードをサポートするように変更書き込み非同期クライアントを後押し

します。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_serviceio_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 
}

 

おすすめ

転載: www.cnblogs.com/luhouxiang/p/11084266.html