|
Boost Users : |
Subject: [Boost-users] [asio] Incorrect reporting of bytes transferred in write handler in 1.54
From: Darren (darodo_at_[hidden])
Date: 2013-07-11 02:18:36
Is anybody else seeing problems with the bytes_transferred reported to the
write_handler after a successful async_write?
I am seeing a value of zero despite the fact that the peer receives the
bytes and no error is reported to the write_handler.
My example code when built against 1.54 exhibits the problem whereas
building against 1.53 works correctly.
I am running on Windows 7 with MSVC 2010.
A couple of notes:
* I only see the problem when the number of threads is > 1, even though the
handlers are invoked on a strand.
* Defining BOOST_ASIO_DISABLE_IOCP makes everything work properly.
When running my code a failure shows itself like this:
Client: Writing value 85
Server: Received 4 bytes, value 85
Client: bytesWritten = 0
In other words, the client used async_write to send 4 bytes with long value
85 the server. The server received these bytes. The client write_handler
was called with no error but a bytes_transferred value of 0.
Is there something I don't understand or is this a problem introduced in
1.54?
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
using namespace boost::asio;
const std::size_t NumThreads = 2;
const unsigned short Port = 12345;
// Prevent interleaved output
boost::mutex logMutex;
struct Server
{
Server(io_service& svc) :
m_socket(svc),
m_acceptor(svc, ip::tcp::endpoint(ip::tcp::v4(), Port)),
m_buffer(0)
{ }
void Run()
{
m_acceptor.accept(m_socket);
// Simple blocking reads
while(std::size_t bytesRead =
read(m_socket, buffer(&m_buffer, sizeof(m_buffer))))
{
boost::mutex::scoped_lock lock(logMutex);
std::cout << "Server: Received " << bytesRead
<< " bytes, value " << m_buffer << std::endl;
}
}
ip::tcp::socket m_socket;
ip::tcp::acceptor m_acceptor;
unsigned long m_buffer;
};
struct Client
{
Client(io_service& svc) :
m_strand(svc),
m_socket(svc),
m_buffer(0)
{
m_socket.connect(
ip::tcp::endpoint(ip::address_v4::from_string("127.0.0.1"), Port));
ScheduleWrite();
}
void WriteHandler(const boost::system::error_code& err,
std::size_t bytesWritten)
{
assert(!err);
if(bytesWritten != sizeof(m_buffer))
{
boost::mutex::scoped_lock lock(logMutex);
std::cout << "Client: bytesWritten = " << bytesWritten <<
std::endl;
return;
}
ScheduleWrite();
}
void ScheduleWrite()
{
{
boost::mutex::scoped_lock lock(logMutex);
std::cout << "Client: Writing value " << ++m_buffer << std::endl;
}
async_write(m_socket, buffer(&m_buffer, sizeof(m_buffer)),
m_strand.wrap(
std::bind(&Client::WriteHandler, this,
std::placeholders::_1, std::placeholders::_2)));
}
io_service::strand m_strand;
ip::tcp::socket m_socket;
unsigned long m_buffer;
};
int main(int argc, char* argv[])
{
boost::asio::io_service svc;
Server server(svc);
Client client(svc);
boost::thread_group threads;
for(int n = 0; n < NumThreads; ++n)
threads.create_thread(std::bind(&io_service::run, &svc));
server.Run();
return 0;
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net