スタンドアロン asio を使用して、read_some でサーバーを実装しました。私のサーバーループは、ソケットから受信したすべてのデータを蓄積します。以下の簡素化されたコードは正しく動作しませんが、inbuf.prepare() ステートメントをループに移動することで修正できます。
asio::streambuf inbuf;
asio::streambuf::mutable_buffers_type inbufs = inbuf.prepare(4096);
while( connected )
{
asio::error_code ec;
size_t bytes_read = Socket().read_some(inbufs,ec);
inbuf.commit(bytes_read);
std::string s = std::string(asio::buffers_begin(inbufs),
asio::buffers_begin(inbufs) + inbuf.size());
inbuf.consume(bytes_read);
}
prepare() がループの外にあり、接続が確立されてから読み取られた合計バイト数が 4096 境界を超える場合、 string はその境界までのデータのみを保持します。つまり、s は bytes_read よりも短くなります。prepare() をループの外に置きたい場合は、次のような消費ループが必要になると推測しましたが、これもうまくいきませんでした。
asio::streambuf inbuf;
asio::streambuf::mutable_buffers_type inbufs = inbuf.prepare(4096);
while( connected )
{
asio::error_code ec;
size_t bytes_read = Socket().read_some(inbufs,ec);
while(bytes_read > 0)
{
inbuf.commit(bytes_read);
std::string s = std::string(asio::buffers_begin(inbufs),
asio::buffers_begin(inbufs) + inbuf.size());
inbuf.consume(inbuf.size());
bytes_read -= s.size();
}
}
prepare() の役割と、なぜ繰り返し呼び出す必要があるのか を明確にすることはできますか?