We have boost asio ssl server that reads data from a client. We have a requirement to perform actual read of the data in our own code as oppose to read directly by boost async_read_some() routines by passing a buffer to it. Hence we pass null_buffers() to async_read_some() and later do the actual data read using socket->read_some() API. Our sockets are all always non-blocking for read and write. http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/overview/core/reactor.html
This works fine with normal stream (tcp) socket. However, with ssl socket, it is not working correctly.
If we don't do (2), then not all data is received, when large amounts of data needs to be read. If we do (2), all data is correctly received (over many read callbacks), but the read callback keeps getting called even after all data has been read and when there is no more data to read...
To verify the same, I used the example boost ssl server and client code and notice a similar behavior with following change to the server code http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/example/ssl/server.cpp handle_read() call back constantly gets called for ever... If we use normal boost stream (tcp) socket (not boost ssl), then we do not see such callbacks when no data is available to read.
We see the same behavior even with the latest boost and ssl code as well. Is null_buffers() read/write mode with ssl socket well tested and supported ? I could not find much documentation for this any where..
Can some one please help. Thank you so much!
diff --git a/server.cc b/server.cc
index 3f2b028..bfd65c7 100644
--- a/server.cc
+++ b/server.cc
@@ -40,7 +40,10 @@ public:
{
if (!error)
{
- socket_.async_read_some(boost::asio::buffer(data_, max_length),
+ socket().non_blocking(true);
+
+ // socket_.async_read_some(boost::asio::buffer(data_, max_length),
+ socket_.async_read_some(boost::asio::null_buffers(),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
@@ -56,6 +59,8 @@ public:
{
if (!error)
{
+ boost::system::error_code err;
+ bytes_transferred = socket_.read_some(boost::asio::mutable_buffers_1(boost::asio::buffer(data_, max_length)), err);
boost::asio::async_write(socket_,
boost::asio::buffer(data_, bytes_transferred),
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
+
+ // Post for read again..
+ socket_.async_read_some(boost::asio::null_buffers(),
+ boost::bind(&session::handle_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));