[免責事項]私はブーストするのが新しいです。async_sendデータが送信されていません
ブースト:: ASIOにみると、以下の機能を持つ単純な非同期TCPサーバーを作成してみました:データを受信した場合は接続した場合、データ
- を==時間は、その後、事前に定義された文字列(「何か他のものが要求された」)
問題を返す他に、現在の日時を返しますが を、 async_sendを使ってデータを送信すると、接続を受け入れてデータを受信しますが、エラーはなく、bytes_transferredの値は正しいですが、クライアント側で空のデータを受け取ります。
handle_accept(handle_readの代わりに)からデータを送信しようとすると、正常に動作します。
実装: 私はブーストASIOのチュートリアルに取り組んでhereが見つかりました: は基本的にアクセプタを開始し、リスニング開始すること、tcp_serverオブジェクトをインスタンス化します。下図のように:
int main()
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
とtcp_server中を:
class tcp_server
{
public:
tcp_server(boost::asio::io_service& io_service)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))
{
start_accept();
}
private:
void start_accept()
{
using std::cout;
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_io_service());
acceptor_.async_accept(new_connection->socket(),
boost::bind(&tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
cout << "Done";
}
...
}
接続が承認されると、以下のように、私はそれを処理しています:
:以下void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
}
start_accept();
}
はtcp_connection::start()
方法であり、
void start()
{
boost::asio::async_read(socket_, boost::asio::buffer(inputBuffer_),
boost::bind(&tcp_connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
/* the snippet below works here - but not in handle_read
outputBuffer_ = make_daytime_string();
boost::asio::async_write(socket_, boost::asio::buffer(outputBuffer_),
boost::bind(&tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));*/
}
そしてhandle_read
に:
void handle_read(const boost::system::error_code& error, size_t bytes_transferred)
{
outputBuffer_ = make_daytime_string();
if (strcmp(inputBuffer_, "time"))
{
/*this does not work - correct bytes_transferred but nothing shown on receiving end */
boost::asio::async_write(socket_, boost::asio::buffer(outputBuffer_),
boost::bind(&tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
outputBuffer_ = "Something else was requested";//, 128);
boost::asio::async_write(socket_, boost::asio::buffer(outputBuffer_),
boost::bind(&tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
handle_write
を以下に示します。
void handle_write(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
std::cout << "Bytes transferred: " << bytes_transferred;
std::cout << "Message sent: " << outputBuffer_;
}
else
{
std::cout << "Error in writing: " << error.message();
}
}
注意をhandle_write
に関する次の(、これは本当に奇妙なことです):
- なしありエラー
- bytes_transferred変数には、corr ECT値
- outputBuffer_はそれにもかかわらず、パッケージは、(データが関係している限り)、クライアント側(Packet Sender)が空で受信
(AS handle_readで設定)が正しい値を有します。
完全なコードはhereです。
あなたが空のデータを受け取ったとすると、0バイト(eof)の受信が完了するか、async_readが完了しないことを意味しますか?なぜハンドラ関数のエラーコードをチェックしていないのですか? –
@RichardHodges "Packet Sender"アプリケーションをクライアントとして使用しています。受信したtcpパケットのデータ部分を見ると、それは空(データ部分なし)です。上記のコードでは、inputBuffer_が正しいことを明確にしたいと思います。私はエラーをチェックしていません、私はEOF(これは私が普通だと思う、ストリーム全体を読んでいる)を受け取っていたからです。私はEOF以外のすべてのエラーをチェックします。私はまた、handle_writeを含めるように私の質問を編集します。 – Lefteris
asio :: async_readとeofエラーに注意してください。 async_readフリー関数は合成された操作です。 bytes_transferredが非ゼロであるとき、eofを示すことが可能である。この場合、データを受け入れ、必要に応じてeofアクションを実行する必要があります(そうでない場合は、次の読み込み時に0バイトで別のeofエラーが発生するため、このオプションのステップをスキップするかどうかは関係ありません) 。 –