|
Boost : |
Subject: [boost] [asio] Randomly having problems reading from the socket
From: Torben Wiggerich (torben.wiggerich_at_[hidden])
Date: 2011-05-02 08:28:20
Hi all,
I have some problems using the boost.asio.read for a TCP-socket. So far
it works fine, but it randomly stops the transfer for at least 5 seconds.
To resolve the error I used a simple synchronous server and client from
the boost examples and modified it too send a larger amount of data.
(307400 Bytes; this size comes from the program I'm trying to get run).
On the client side I also changed the reading from the socket to read
the complete data with boost.asio.read and transfer_all as argument.
Both, server and client, measure the time for sending and reading to the
socket and will give an error if it needs more than 1 second.
Here is the sourcecode for the server:
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using boost::asio::ip::tcp;
using namespace boost::posix_time;
int main()
{
try
{
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 8002));
tcp::socket socket(io_service);
acceptor.accept(socket);
unsigned char * array = new unsigned char[307400];
for (;;)
{
boost::system::error_code ignored_error;
ptime startTime = microsec_clock::universal_time();
boost::asio::write(socket, boost::asio::buffer( array,
307400 ),
boost::asio::transfer_all(), ignored_error);
time_duration neededTime = microsec_clock::universal_time()
- startTime;
if ( neededTime.total_milliseconds() > 1000 ) {
std::cout << "ERROR needed too much time: " <<
neededTime.total_milliseconds() << "ms" << std::endl;
}
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
My client sourcecode:
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using boost::asio::ip::tcp;
using namespace boost::posix_time;
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr << "Usage: client <host>" << std::endl;
return 1;
}
boost::asio::io_service io_service;
boost::asio::ip::tcp::endpoint endpoint(
boost::asio::ip::address::from_string( argv[1] ), 8002 );
tcp::socket socket(io_service);
boost::system::error_code error = boost::asio::error::host_not_found;
socket.connect( endpoint, error );
if (error)
throw boost::system::system_error(error);
int counter = 0;
unsigned char* array = new unsigned char[307400];
for (;;)
{
boost::system::error_code error;
ptime startTime = microsec_clock::universal_time();
size_t len = boost::asio::read( socket,
boost::asio::buffer( array, 307400 ),
boost::asio::transfer_all(),
error );
time_duration neededTime = microsec_clock::universal_time() -
startTime;
if ( error ) {
printf( "body read error %s\n", error.message().c_str() );
}
if ( counter % 5000 == 0 ) {
std::cout << "passed: " << counter << "\r";
}
++counter;
if ( neededTime.total_milliseconds() > 1000 ) {
std::cout << "ERROR needed too much time: " <<
neededTime.total_milliseconds() << "ms" << std::endl;
}
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
To reproduce the error just let it run for a while. It can take up to 30
minutes or even more...
After a while it will produce the line: "ERROR needed too much time:
5007ms". Maybe with slightly different times, but all around 5 seconds.
I tested it on different machines with Windows Vista and Seven.
So am I'm doing sth. wrong? Is the reading from the socket correct?
I'm using boost version 1.44.
Kind regards
Torben Wiggerich
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk