ソケット経由で送信されるシリアル化された構造があります。フィールドの1つに残りのデータのサイズが含まれているため、チャンクで読み取る必要があります。最初の数バイトを読み取り、長さを調べて残りを読み取る必要があります。これは私が持っているものです:
boost::asio::streambuf buffer;
boost::system::error_code err_code;
// here I need to read only first 16 bytes
boost::asio::read(socket, buffer, err_code);
std::istream is(&buffer);
boost::archive::binary_iarchive ia(is);
ia >> my_struct;
私は見てきました
boost::asio::async_read(s, boost::asio::buffer(data, size), handler);
ただし、データを読み取ってブースト:: asio :: bufferすることしかできません。 boost :: asio :: streambufでも同じことができるかどうか疑問に思っていますか?前もって感謝します。
boost::asio::read()
と boost::asio::async_read()
の両方にオーバーロードがあり、 _boost::asio::basic_streambuf
_ のインスタンスを受け入れます。そのバッファとして:
_read(SyncReadStream&, basic_streambuf&);
read(SyncReadStream&, basic_streambuf&, CompletionCondition);
read(SyncReadStream&, basic_streambuf&, boost::system::error_code&);
read(SyncReadStream&, basic_streambuf&, CompletionCondition,
boost::system::error_code&);
async_read(AsyncReadStream&, basic_streambuf&, ReadHandler);
async_read(AsyncReadStream&, basic_streambuf&, CompletionCondition,
ReadHandler);
_
CompletionConditionを受け入れないオーバーロードを呼び出す場合、それに関連するオーバーロードを boost::asio::transfer_all()
のCompletionConditionで呼び出すのと同じであり、操作に streambuf.max_size()
バイト。
既知のバイト数をstreambufに読み込むには、次のいずれかを使用します。
boost::asio::transfer_exactly(n)
CompletionConditionは、構成された操作から転送されるバイト数を制限します。
_std::size_t n = // ...
boost::asio::read(socket, streambuf,
boost::asio::transfer_exactly(n), error);
_
バッファとして機能する出力シーケンスを明示的に作成し、読み取られたバイトをstreambufの入力シーケンスにコミットします。
_std::size_t n = // ...
std::size_t bytes_transferred = boost::asio::read(socket,
streambuf.prepare(n), // creates a boost::asio::buffer
error);
streambuf.commit(bytes_transferred);
_
これが完全な例です デモンストレーション これらのアプローチの両方:
_#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
// This example is not interested in the handlers, so provide a noop function
// that will be passed to bind to meet the handler concept requirements.
void noop() {}
std::string make_string(boost::asio::streambuf& streambuf)
{
return {boost::asio::buffers_begin(streambuf.data()),
boost::asio::buffers_end(streambuf.data())};
}
int main()
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
// Create all I/O objects.
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 0));
tcp::socket server_socket(io_service);
tcp::socket client_socket(io_service);
// Connect client and server sockets.
acceptor.async_accept(server_socket, boost::bind(&noop));
client_socket.async_connect(acceptor.local_endpoint(), boost::bind(&noop));
io_service.run();
// Write to server.
boost::asio::streambuf write_buffer;
std::ostream output(&write_buffer);
output << "abc";
std::cout << "Writing: " << make_string(write_buffer) << std::endl;
auto bytes_transferred = boost::asio::write(server_socket, write_buffer);
// Read from client.
boost::asio::streambuf read_buffer;
bytes_transferred = boost::asio::read(client_socket, read_buffer,
boost::asio::transfer_exactly(bytes_transferred));
std::cout << "Read: " << make_string(read_buffer) << std::endl;
read_buffer.consume(bytes_transferred); // Remove data that was read.
// Write to server.
output << "def";
std::cout << "Writing: " << make_string(write_buffer) << std::endl;
bytes_transferred = boost::asio::write(server_socket, write_buffer);
// Read from client.
bytes_transferred = boost::asio::read(client_socket,
read_buffer.prepare(bytes_transferred));
read_buffer.commit(bytes_transferred);
std::cout << "Read: " << make_string(read_buffer) << std::endl;
read_buffer.consume(bytes_transferred); // Remove data that was read.
}
_
出力:
_Writing: abc
Read: abc
Writing: def
Read: def
_