2017-05-02 13 views
1

私はネットワークプログラミングを学んでおり、boost-asioの使用を推奨しました。私は昼間のチュートリアル1 & 2で:http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/tutorial.htmlをして、サーバーがシリアル化されたオブジェクトを送信するクライアントに反応し、結果を返すように変更したいと思った。クライアントがhandleReadループに座ってサーバーが終了するのを待つという意図で、次のようなシーケンスを使用すると想像しました。ソケットが閉じられるまでデータが送信されない

サーバー:
accept - > handleRead - > process_read - >アクションを実行する - - > handleWrite

クライアント:
は、接続 - > handleWrite - > handleRead - > process_read

しかし

、私はこれを行うと、サーバーとクライアントの両方が何らかの形で私が持っている読み取りループにはまりセットアップ。これはクライアント側で期待されますが、クライアントは読み取りループに入る前にデータの書き込みと送信を行う必要があります。クライアント側で接続を切断するか、書いた書込み機能の最後にsocket.close()を追加すると、残りのすべてのサーバーステップがクライアントから送信された適切なデータで実行されます。

私はもともと、この問題は、Nagleアルゴリズムが有効にされているとしなければならなかったと思ったが、

boost::asio::ip::tcp::no_delay option(true); 
socket.set_option(option); 

を追加すると、まったく助けにはなりませんでした。私はこのデータをソケットをフラッシュするように送るためのチュートリアルになかったものを見逃していますか?

void myClient::handle_read() 
{ 
    boost::system::error_code e; 
    try 
    {  
     for (;;) 
     { 
      size_t len = boost::asio::read(socket, boost::asio::buffer(inBuffer), e); 

      std::cout << "Client Received: "; 

      if (e == boost::asio::error::eof) 
      { 
       break; 
      } 

      else if (e) 
      { 
       throw boost::system::system_error(e); 
      } 
     } 
    } 

    catch (std::exception& e) 
    { 
     std::cerr << e.what() << std::endl; 
     std::cout << e.what() << std::endl; 
    } 
} 

template <typename T> 
void handleWrite(T& t) 
{ 
    std::ostringstream archive_stream; 
    std::string tempString; 

    boost::archive::text_oarchive archive(archive_stream); 
    archive << t; 

    tempString = archive_stream.str(); 
    outBuffer.assign(tempString.begin(), tempString.end()); 

    boost::system::error_code ignored_error; 
    size_t sent = boost::asio::write(socket, boost::asio::buffer(outBuffer), ignored_error); 
    std::cout << sent << std::endl; 
} 

私はC++とネットワークプログラミングにはかなり新しいので、追加のドキュメントもありがとうございます。ありがとう!

+0

チュートリアルのオリジナルプログラムは機能しますか?あなたは何を変えましたか? –

+0

はい、あります。私はかなりの変更を加えましたが、達成しようとしていた最大の問題は、接続直後にサーバーからメッセージを受け取るのではなく、クライアント - >サーバー - >クライアントからメッセージを送信できることでした。 – ipwnatlyfe

+0

あなたの質問からは全く分かりません。私は、最小限の変更を切り分けて正確に投稿することをお勧めします。 –

答えて

1

もちろん、あなたは読書ループに悩まされています。スチームの終わりまでは終了しません。ストリームの終了は、ピアがソケットを閉じるときにのみ発生します。

+0

これがうまくいくとは思うが、サーバーがhandle_write()の部分でクライアントから何かを受け取るのを待っているhandle_read()ループに入っているが、handle_write()の間に何も書き込まれずにクライアントが終了するそれが壊れたまでそれが書いたものを送信することなく、それ自身のhandle_read()ループに巻き込まれてしまいます。あなたは、メッセージを送信するためにクライアントhandle_write()とhandle_read()の間に何かを追加しなければならないと言っていますか?あなたはどういう意味ですか? – ipwnatlyfe

+0

Data *は送信されますが、ストリームの終わりまたはエラーが発生するまで読み取りループは終了しません。これはあなたの部分のバグです。あなたは到着時にデータで何かをする必要があります。 – EJP

+0

単に物事を読んで、 'std :: cout <<"クライアント(サーバ)を印刷した場合、それは意味がありますが、size_t len = boost :: asio :: read(socket、boost :: asio :: buffer(inBuffer)、e);ライン。 クライアントが実際に何かを書いたのであれば、何も読んでいない状態でそこに詰まることはないでしょうか。ループ内にバッファを印刷する行を追加しましたが、ソケットが閉じられるまで何もしません。 – ipwnatlyfe

関連する問題