c++ - Boost asio TCP + google proto -
i first footsteps boost asio , google proto. defined small test message
message test { optional string test=1; optional int32 value=2; }
and 1 async boost asio server response following function:
void start() { test test; test.set_test("test"); test.set_value(44444); test.printdebugstring(); boost::asio::async_write(socket_, boost::asio::buffer(test.serializeasstring()), boost::bind(&tcp_connection::handle_write, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); }
my test client is
#include <iostream> #include <boost/array.hpp> #include <boost/asio.hpp> #include "test.pb.h" using boost::asio::ip::tcp; int main(int argc, char* argv[]) { try { boost::asio::io_service io_service; tcp::resolver resolver(io_service); tcp::endpoint end_point(boost::asio::ip::address::from_string("127.0.0.1"), 15000); tcp::socket socket(io_service); socket.connect(end_point); std::string data; (;;) { boost::array<char, 128> buf; boost::system::error_code error; size_t len = socket.read_some(boost::asio::buffer(buf), error); if (error == boost::asio::error::eof) { test test; test.parsefromstring(data); test.printdebugstring(); break; // connection closed cleanly peer. } else if (error) throw boost::system::system_error(error); // other error. data.append(buf.begin(), buf.end()); } } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return 0; }
if call server client few times different outputs:
test: "test" value: 44444 533 { } test: "test" value: 44444 1644{ } test: "test" value: 44444
the last output expected rest wrong. dont understand why bigger output have on server :
test: "test" value: 44444
anyone has idea why "1644{ }" ?
i think eof wrong or?
edit
message header { required int32 size=1; }
new start
void start() { boost::asio::async_read(socket_, boost::asio::buffer(m_headerdata, m_sizeofheader), boost::bind(&tcp_connection::handle_read_header, this, boost::asio::placeholders::error)); }
members:
const size_t m_sizeofheader = sizeof(header::default_instance().serializeasstring()); boost::array<char, sizeof(header::default_instance().serializeasstring())> m_headerdata; void handle_read_header(const boost::system::error_code& error_code) { if (!error_code) { header header; header.parsefromstring(std::string(m_headerdata.begin(), m_headerdata.end())); header.printdebugstring(); } else { std::cout << error_code.message()<< "error delete read \n"; delete this; }
i tried header on way now, following errors:
operation canceled or bad file descriptor
my new client sends :
header header; header.set_size(101); boost::asio::write(socket,boost::asio::buffer(header.serializeasstring())) ;
i think problem variable m_sizeofheader wrong... on server side 8, , when print output of write on client 2...
i dont understand why sizes header not fixed... have 1 required field
you ignoring number of bytes read (len
) , append garbage data
with:
data.append(buf.begin(), buf.end());
try instead:
data.append(buf.begin(), buf.begin() + len);
also code correctly work if single message sent , socket gracefully closed (with shutdown
) after that. in more complex scenario you'll need kind of protocol allows determine message bounds. instance, can send message size in first 2 bytes before message , on receiving side first read 2 bytes expected message size, read message body.
Comments
Post a Comment