I am writing a C++11 application on Visual Studio 2015, and I use ASIO (not with boost). I followed the example in the server file, but changed all boost code to C++11.
The code works with a client which can connect and get the data. I modified the server code to use different timer for read and write. I also removed all the udp broadcast codes.
Code
void start() {
std::cout << std::endl << "TCP Session start called " <<
"read timeout = "<<&readTimeout_<<" write timeout = "<<&writeTimeout_<<std::endl;
std::string firstPacket = process(input_buffer_); // at this time, we require the process to judge
deliver(firstPacket);
await_output();
output_deadline_.async_wait(
std::bind(&TCP_Session::check_deadline, shared_from_this(), &output_deadline_)
);
start_read();
input_deadline_.async_wait(
std::bind(&TCP_Session::check_deadline, shared_from_this(), &input_deadline_)
);
}
void deliver(const std::string& msg) {
output_queue_.push_back(msg + "\n"+endChar);
std::cout << "delivered one" << std::endl;
// Signal that the output queue contains messages. Modifying the expiry
// will wake the output actor, if it is waiting on the timer.
non_empty_output_queue_.expires_at(std::chrono::high_resolution_clock::time_point::min());
}
void await_output() {
if (stopped())
return;
if (output_queue_.empty()) {
// There are no messages ready to be sent. The actor goes to sleep by waiting on the non_empty_output_queue_ timer.
// When a new message is added, the timer will be modified and the actor will wake.
non_empty_output_queue_.expires_at(std::chrono::high_resolution_clock::time_point::max());
non_empty_output_queue_.async_wait(
std::bind(&TCP_Session::await_output, shared_from_this()));
} else {
start_write();
}
}
void start_write() {
// Set a deadline for the write operation.
output_deadline_.expires_from_now(writeTimeout_);
// Start an asynchronous operation to send a message.
asio::async_write(socket_,
asio::buffer(output_queue_.front()),
std::bind(&TCP_Session::handle_write, shared_from_this(), std::placeholders::_1));
}
void handle_write(const asio::error_code& ec) {
if (stopped())
return;
if (!ec) {
output_queue_.pop_front();
await_output();
} else {
std::cout << "error when write ec=" << ec << std::endl;
stop();
}
}
std::chrono::milliseconds readTimeout_ = std::chrono::milliseconds(600000); //C++11 style
std::chrono::milliseconds writeTimeout_ = std::chrono::milliseconds(3000); //C++11 style
Question
If the client connects, and doesn't send anything to server for 3 seconds, the server timeout. I know I put 3 seconds there for the writeTimeout_, but shouldn't it timeout when the write is not successful? My client can see the packet sent by the server.
Since I modified the original code and removed the udp part, should I remove the timeout for sending packet? Or should I adjust the timer after the async_write is successful?
Aucun commentaire:
Enregistrer un commentaire