Observation
I built a demo application according to this server example using ASIO after I used C++11 std to replace everything originally in boost. The server can show that class member tcp_session::start()
is called only after the client connects which is good indication that the server accepts the connection from the client.
However, I saw nothing received by handle_read
while the clients sends a lot of data. I got some std::cout in handle_read and stop. I put the timeout to be 6 seconds now and found this:
The start
is called right after the client connects, and then nothing indicating that the handle_read
is called, but after 6 seconds, stop()
is called, and then handle_read
is called because of the timeout and socket_.isOpen()
is false.
Then I found that if I change async_read
to async_read_until
that was commented originally by me, then the handle_read
will be called andthe socket_.isopen
is true so I can really see the packets.
Question:
The delimiter was there but I don't want one. How do I async read a whole TCP string without a delimiter? Why async_read doesn't work? Should it work like this? Is there anything wrong in my code?
I am using VS2015 and test on localhost.
Answer
TCP doesn't have boundary so I decided to put special character to indicate the end of each packet.
Here are some relevant code:
class tcp_session : public subscriber, public std::enable_shared_from_this<tcp_session> {
public:
void start() {
std::cout<<"started"<<std::endl;
channel_.join(shared_from_this());
start_read();
input_deadline_.async_wait(
std::bind(&tcp_session::check_deadline, shared_from_this(), &input_deadline_)
);
await_output();
output_deadline_.async_wait(
std::bind(&tcp_session::check_deadline, shared_from_this(), &output_deadline_)
);
}
private:
bool stopped() const {
return !socket_.is_open();// weird that it is still not open
}
void start_read() {
// Set a deadline for the read operation.
input_deadline_.expires_from_now(timeout_); //was std::chrono::seconds(30) in example
char a = 0x7F;
// Start an asynchronous operation to read a 0x7F-delimited message or read all
//asio::async_read_until(socket_, input_buffer_, a, std::bind(&TCP_Session::handle_read, shared_from_this(), std::placeholders::_1));
asio::async_read(socket_, input_buffer_,
std::bind(&TCP_Session::handle_read, shared_from_this(), std::placeholders::_1));
}
void handle_read(const asio::error_code& ec) {
if (stopped()) // it thinks it stopped and returned without processing
return;