私はネットワークプログラミングを学んでおり、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++とネットワークプログラミングにはかなり新しいので、追加のドキュメントもありがとうございます。ありがとう!
チュートリアルのオリジナルプログラムは機能しますか?あなたは何を変えましたか? –
はい、あります。私はかなりの変更を加えましたが、達成しようとしていた最大の問題は、接続直後にサーバーからメッセージを受け取るのではなく、クライアント - >サーバー - >クライアントからメッセージを送信できることでした。 – ipwnatlyfe
あなたの質問からは全く分かりません。私は、最小限の変更を切り分けて正確に投稿することをお勧めします。 –