2017-10-23 5 views
0

부스트 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을 위해 streambuffer를 사용하고 istreambuf_iterators를 사용한다. 약간의 실험을 한 후에 나는 문제를 발견했다 : std :: copy_n은 반복자로 이상한 일을하고있다. while 루프를 사용하고 ++ 연산자를 호출하면 문제가 없습니다. 커밋을 사용하지 않거나 streambuf에서 ostream 또는 istream을 만드는 것으로 잘못된 것이 있습니까? – Gustavo

+2

istream 또는 ostream에서 streambuffer를 사용하면 커밋/소비 메커니즘이 완성됩니다. –

답변

1

덧글 외에도 asio::streambuf과 상호 작용하는 두 가지 방법을 보여주는 간단한 데모 프로그램이 있습니다.

편도는 streambuf를 I/O 스트림으로 랩핑하고, 다른 방법은 준비/커밋 및 데이터/소비로 직접 액세스를 사용합니다.

#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"; 
}