2017-10-23 14 views
0

boost asioのストリームからの読み込みに問題があります。 async_read_untilの最初の呼び出しは私に460バイトの転送を与えます(私はwiresharkでそれを調べました)。その後、私はistreambuf_iteratorでstd :: copy_nを使うためにstreambufポインタで初期化されたistreamを使います。それは正常に動作し、std :: copy_nのターゲットは区切り文字シーケンスまで要求を保持します。boost asioからの読み込みstreambufはバッファ内のバイトを保持します

次回のasync_read_untilの呼び出しの後に異常なことが起こります。最後の文字はstreambufから読み込まれなかったので、次のハンドラ呼び出しはリクエストの実際のサイズよりも1バイト多くを返します。

istreamをasioのstreambufで使用する際に制限がありますか?

+0

あなたは 'commit()'と 'consume()'関数を正しく使っていますか?確認するために私のIDEにコピーをコピーできる、最小限の完全なコードを表示できますか? –

+0

私はコミットまたは消費機能を使用しません。私はstd :: istreamにストリームバッファを使い、istreambuf_iteratorsを使用します。ちょっと試してみたところ、問題が見つかりました:std :: copy_nはイテレータで変なことをしています。 whileループを使用し、++演算子を呼び出すとうまく動作します。コミットや消費を使わず、streambufからostreamやistreamを作成するだけで何か問題はありますか? – Gustavo

+2

ストリームバッファをistreamまたはostreamの中で使用すると、コミット/消費の仕組みが完了します。 –

答えて

1

コメントに加えて、asio::streambufと対話する2つの方法を示す小さなデモプログラムがあります。

片方向ストリームはstreambufをi/oストリームでラップし、もう一方はprepare/commitとdata/consumeで直接アクセスを使用します。

#include <boost/asio.hpp> 
#include <iostream> 
#include <string> 
#include <algorithm> 
#include <memory> 

namespace asio = boost::asio; 

void direct_insert(asio::streambuf& sb, std::string const& data) 
{ 
    auto size = data.size(); 
    auto buffer = sb.prepare(size); 
    std::copy(begin(data), end(data), asio::buffer_cast<char*>(buffer)); 
    sb.commit(size); 
} 

void stream_insert(asio::streambuf& sb, std::string const& data) 
{ 
    std::ostream strm(std::addressof(sb)); 
    strm << data; 
} 

std::string extract_istream(asio::streambuf& sb) 
{ 
    std::istream is(std::addressof(sb)); 
    std::string line; 
    std::getline(is, line); 
    return line; 
} 

std::string extract_direct(asio::streambuf& sb) 
{ 
    auto buffer = sb.data(); 
    auto first = asio::buffer_cast<const char*>(buffer); 
    auto bufsiz = asio::buffer_size(buffer); 
    auto last = first + bufsiz; 

    auto nlpos = std::find(first, last, '\n'); 

    auto result = std::string(first, nlpos); 

    auto to_consume = std::min(std::size_t(std::distance(first, nlpos) + 1), bufsiz); 
    sb.consume(to_consume); 
    return result; 
} 

int main() 
{ 
    asio::streambuf buf; 
    direct_insert(buf, "The cat sat on the mat\n"); 
    stream_insert(buf, "The cat sat on the mat\n"); 

    auto s1 = extract_direct(buf); 
    auto s2 = extract_istream(buf); 

    std::cout << s1 << "\n" << s2 << "\n"; 
} 
関連する問題