Currently I’m using design when server reads first 4 bytes of stream then read N bytes after header decoding.
But I found that time between first async_read and second read is 3-4 ms. I just printed in console timestamp from callbacks for measuring. I sent 10 bytes of data in total. Why it takes so much time to read?
I running it in debug mode but I think that 1 connection for debug is
not so much to have a 3 ms delay between reads from socket. Maybe I need
another approach to cut TCP stream on “packets”?
UPDATE: I post some code here
void parseHeader(const boost::system::error_code& error)
{
cout<<"[parseHeader] "<<lib::GET_SERVER_TIME()<<endl;
if (error) {
close();
return;
}
GenTCPmsg::header result = msg.parseHeader();
if (result.error == GenTCPmsg::parse_error::__NO_ERROR__) {
msg.setDataLength(result.size);
boost::asio::async_read(*socket,
boost::asio::buffer(msg.data(), result.size),
(*_strand).wrap(
boost::bind(&ConnectionInterface::parsePacket, shared_from_this(), boost::asio::placeholders::error)));
} else {
close();
}
}
void parsePacket(const boost::system::error_code& error)
{
cout<<"[parsePacket] "<<lib::GET_SERVER_TIME()<<endl;
if (error) {
close();
return;
}
protocol->parsePacket(msg);
msg.flush();
boost::asio::async_read(*socket,
boost::asio::buffer(msg.data(), config::HEADER_SIZE),
(*_strand).wrap(
boost::bind(&ConnectionInterface::parseHeader, shared_from_this(), boost::asio::placeholders::error)));
}
As you see unix timestamps differ in 3-4 ms. I want to understand why so many time elapse between parseHeader and parsePacket. This is not a client problem, summary data is 10 bytes, but i cant sent much much more, delay is exactly between calls. I’m using flash client version 11. What i do is just send ByteArray through opened socket. I don’t sure that delays on client. I send all 10 bytes at once. How can i debug where actual delay is?
There are far too many unknowns to identify the root cause of the delay from the posted code. Nevertheless, there are a few approaches and considerations that can be taken to help to identify the problem:
BOOST_ASIO_ENABLE_HANDLER_TRACKINGand Boost.Asio will write debug output, including timestamps, to the standard error stream. These timestamps can be used to help filter out delays introduced by application code (parseHeader(),parsePacket(), etc.).sizefield as two bytes in network-byte-order and the server is handling the field as a raw short, then upon receiving a message that has a body size of10:async_readreading10bytes. The read operation should complete quickly as the socket already has the10byte body available for reading.async_readreading2560bytes. The read operation will likely remain outstanding, as far more bytes are trying to be read than is intended.Here is a simple example from which I started:
A few notes about the implementation:
boost::asio::async_read, noise is minimized by:shared_from_this()orstrand::wrap.I compiled on CentOS 5.4 using gcc 4.4.0 and Boost 1.50. To drive the data, I opted to send 1000 bytes using netcat:
$ ./a.out > output & [1] 18623 $ echo "$(for i in {0..1000}; do echo -n "0"; done)" | nc 127.0.0.1 33333 [1]+ Done ./a.out >output $ tail output Delta: 0 ms Delta: 0 ms Delta: 0 ms Delta: 0 ms Delta: 0 ms Delta: 0 ms Total Start: 2012-Sep-10 21:22:45.585780 End: 2012-Sep-10 21:22:45.586716 Delta: 0 msObserving no delay, I expanded upon the example by modifying the
boost::asio::async_readcalls, replacingthiswithshared_from_this()and wrapping theReadHandlerss withstrand_.wrap(). I ran the updated example and still observed no delay. Unfortunately, that is as far as I could get based on the code posted in the question.Consider expanding upon the example, adding in a piece from the real implementation with each iteration. For example:
msgvariable’s type to control the buffer.parseHeader()andparsePacketfunctions.lib::GET_SERVER_TIME()print.If the example code is as close as possible to the real code, and no delay is being observed with
boost::asio::async_read, then theReadHandlers may be ready-to-run in the real code, but they are waiting on synchronization (the strand) or a resource (a thread), resulting in a delay:io_service::run().