asio::transfer_at_least strange behavior
Hi Is transfer_at_least supposed to return success only if requested number of bytes transferred at once or at all? For example, I want to receive 800 bytes and put them into streambuf using transfer_at_least(800) as completion condition, but I receive 2 chunks of 400 bytes, therefore I never get a success, because transfer_at_least_t always wants more data. I know, there are may be some problems with handler copying, but the name of function is misleading, and may be should be documented. I'm using boost 1.37, may be something has changed in 1.38.
Is transfer_at_least supposed to return success only if requested number of bytes transferred at once or at all?
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/reference/transfer_... "Return a completion condition function object that indicates that a read or write operation **should continue until** a minimum number of bytes has been transferred, or until an error occurs."
For example, I want to receive 800 bytes and put them into streambuf using transfer_at_least(800) as completion condition, but I receive 2 chunks of 400 bytes, therefore I never get a success, because transfer_at_least_t always wants more data.
When 800 bytes are received (at once or by chunks) or error occurs, the completion handler is invoked - that's the effect of this completion condition. If you encounter different behaviour, could you please provide minimal code demonstrating this?
On Thu, Feb 12, 2009 at 10:16 PM, Igor R
Is transfer_at_least supposed to return success only if requested number of
bytes transferred at once or at all?
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/reference/transfer_... "Return a completion condition function object that indicates that a read or write operation **should continue until** a minimum number of bytes has been transferred, or until an error occurs."
For example, I want to receive 800 bytes and put them into streambuf using transfer_at_least(800) as completion condition, but I receive 2 chunks of 400 bytes, therefore I never get a success, because transfer_at_least_t always wants more data.
When 800 bytes are received (at once or by chunks) or error occurs, the completion handler is invoked - that's the effect of this completion condition. If you encounter different behaviour, could you please provide minimal code demonstrating this?
From implementation: class transfer_at_least_t {
Yes, exactly. Code snippet may be uselese, but I'm using something like this: boost::asio::read(sock, buf, boost::asio::transfer_at_least(800), myhandler); and myhandler is never called (because no more data arrives). public: typedef std::size_t result_type; explicit transfer_at_least_t(std::size_t minimum) : minimum_(minimum) { } template <typename Error> std::size_t operator()(const Error& err, std::size_t bytes_transferred) { return (!!err || bytes_transferred >= minimum_) ? 0 : default_max_transfer_size; } private: std::size_t minimum_; }; This handler called after each read operation and bytes_transferred each time is 400, but minimum_ is 800.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Yes, exactly. Code snippet may be uselese, but I'm using something like this: boost::asio::read(sock, buf, boost::asio::transfer_at_least(800), myhandler);
and myhandler is never called (because no more data arrives).
So, probably 800 bytes do not arrive, or there's some other issue.
This handler called after each read operation and bytes_transferred each time is 400, but minimum_ is 800.
Look at the implementation of read(): (Note that bytes_transferred passed to the completion_condition is accumulated each time)
template
On Fri, Feb 13, 2009 at 12:22 AM, Igor R
Yes, exactly. Code snippet may be uselese, but I'm using something like
this: boost::asio::read(sock, buf, boost::asio::transfer_at_least(800), myhandler);
and myhandler is never called (because no more data arrives).
So, probably 800 bytes do not arrive, or there's some other issue.
This handler called after each read operation and bytes_transferred each time is 400, but minimum_ is 800.
Look at the implementation of read(): (Note that bytes_transferred passed to the completion_condition is accumulated each time)
template
std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, boost::system::error_code& ec) { ec = boost::system::error_code(); boost::asio::detail::consuming_buffers< mutable_buffer, MutableBufferSequence> tmp(buffers); std::size_t total_transferred = 0; tmp.set_max_size(detail::adapt_completion_condition_result( completion_condition(ec, total_transferred))); while (tmp.begin() != tmp.end()) { std::size_t bytes_transferred = s.read_some(tmp, ec); tmp.consume(bytes_transferred); * total_transferred += bytes_transferred;* tmp.set_max_size(detail::adapt_completion_condition_result( completion_condition(ec, total_transferred))); } return total_transferred; }
Yes, my bad, sorry for noise. Actually, I've used streambuf to read HTTP response with content-length. But some data was already in buffer. I've changed my code to something like this: contentLength -= boost::asio::buffer_size(m_readBuffer.data()); boost::asio::async_read(m_socket, m_readBuffer, boost::asio::transfer_at_least(contentLength), myhandler); And now everything works fine. Thanks for help.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Igor R
-
Timenkov Yuri