ブーストasioライブラリを使用してtcpサーバーを実装しています。サーバーでは、asio::async_read_some を使用してデータを取得し、asio::write を使用してデータを書き込みます。サーバーコードはそのようなものです。
std::array<char, kBufferSize> buffer_;
std::string ProcessMessage(const std::string& s) {
if (s == "msg1") return "resp1";
if (s == "msg2") return "resp2";
return "";
}
void HandleRead(const boost::system::error_code& ec, size_t size) {
std::string message(buffer_.data(), size);
std::string resp = ProcessMessage(message);
if (!resp.empty()) {
asio::write(socket, boost::asio::buffer(message), WriteCallback);
}
socket.async_read_some(boost::asio::buffer(buffer_));
}
次に、サーバーをテストするクライアントを作成します。コードは次のようなものです
void MessageCallback(const boost::system::error_code& ec, size_t size) {
std::cout << string(buffer_.data(), size) << std::endl;
}
//Init socket
asio::write(socket, boost::asio::buffer("msg1"));
socket.read_some(boost::asio::buffer(buffer_), MessageCallback);
// Or async_read
//socket.async_read_some(boost::asio::buffer(buffer_), MessageCallback);
asio::write(socket, boost::asio::buffer("msg1"));
socket.read_some(boost::asio::buffer(buffer_), MessageCallback);
// Or async_read
//socket.async_read_some(boost::asio::buffer(buffer_), MessageCallback);
クライアントを実行すると、コードは 2 番目の read_some で待機し、出力は次のようになりますresp1
。
最初の read_some を削除すると、出力は にresp1resp2
なります。これは、サーバーが正しいことを行ったことを意味します。
最初の read_some EATは 2 番目の応答のようですが、MessageCallback 関数には応答しません。
メッセージ境界とは?の質問を読みました。、この問題が「メッセージ境界」の問題である場合、最初の read_some は tcp ソケットからストリームの一部のみを取得するため、2 番目の read_some は何かを出力するはずです。
どうすればこの問題を解決できますか?
更新: クライアント バッファーのサイズを 4 に変更しようとしました。その出力は次のようになります。
resp
resp
read_some 関数は、ソケットからの読み取りよりも少し多くのことを行うようです。Boost コードを読んで、それが真実であることを確認します。