Hi Gavin
thanks for the info, I've modified the do_read function as follows:
void do_read() { excep_log( "Start reading"); boost::asio::async_read_until(sk, receive_data, '\n', [this](const boost::system::error_code& ec, std::size_t bytes_transferred) { if (!ec) { boost::asio::streambuf::const_buffers_type bufs = receive_data.data(); std::string str(boost::asio::buffers_begin(bufs), boost::asio::buffers_begin(bufs) + bytes_transferred); receive_data.consume(bytes_transferred); excep_log( "SQL Statement: " + str); do_write(bytes_transferred, rows_affected(str) ); } }); }
The server still crashes, though the error is no longer a "core dump", but a "Segmentation fault".The log file generated shows output as follows:Start: 00: Start reading0: SQL �\�7: 22021 ERROR: invalid byte sequence for encoding "UTF8": 0xba
7: Before write
As you can see, when a session is started (start function), the read_until starts immediately, but at that point the client has only connected and not yet sent a SQL statement (22021 ERROR is a database error).So how can I start a session, but defer the reading until the client has sent an SQL statement ?
Any suggestions would be appreciatedPeter
On Thursday, 7 September 2017, 6:25, Gavin Lambert via Boost-users
I'm a database developer and I'm using boost for the first time. I've copied the echo server & client example from the Boost website http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/examples/cpp11_exam... and modified it somewhat so that when I receive a SQL statement from the client I pass pass it onto a function that performs the db execution. Once executed Ireply back to the client how many rows were affected.
The code works , if I send only a single request at a time from the synchronous client, so I modified the async server so that the read is a read_until. The change now crashes the server.
read_until has a different behaviour from basic reads; you must preserve the streambuf between consecutive calls and consume only the bytes you have been told about. This is because the buffer will contain more data than was actually requested -- the underlying network read will read a block of data that might contain multiple terminator characters, but read_until reports only the data up to (and including) the first terminator each time. In particular:
boost::asio::async_read_until(sk, receive_data, '\n', [this](const boost::system::error_code& ec, std::size_t bytes_transferred) { if (!ec) { boost::asio::streambuf::const_buffers_type bufs = receive_data.data(); std::string str(boost::asio::buffers_begin(bufs), boost::asio::buffers_begin(bufs) + receive_data.size()); do_write(bytes_transferred, rows_affected(str) ); } });
Do not use receive_data.size(); use bytes_transferred instead. Also, after copying the bytes from the buffer into the stream, issue receive_data.consume(bytes_transferred). This tells Asio that the bytes have been processed so it can move on to the next terminator the next time you call async_read_until. There's an example of this at http://coliru.stacked-crooked.com/a/51b5be0caf331187 _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users