0

I'm trying to write a TCP client using several different examples using Asio from Boost 1.60. The connection works properly for probably 30 seconds or so, but disconnects with the error:

The network connection was aborted by the local system

I've attempted to set up a "ping/pong" setup to keep the connection alive but it still terminates. The only previous Stack Overflow answers I've found suggested using Boost's shared_from_this and a shared pointer, which I've adapted my code to use. But the problem persists.

Setting up the Connection object and its thread:

 boost::asio::io_service ios; boost::asio::ip::tcp::resolver res(ios); boost::shared_ptr<Connection> conn = boost::shared_ptr<Connection>(new Connection(ios)); conn->Start(res.resolve(boost::asio::ip::tcp::resolver::query("myserver", "10635"))); boost::thread t(boost::bind(&boost::asio::io_service::run, &ios)); 

Here's the relevant portions of the Connection class (I made sure to use shared_from_this() everywhere else, too):

class Connection : public boost::enable_shared_from_this<Connection> { public: Connection(boost::asio::io_service &io_service) : stopped_(false), socket_(io_service), deadline_(io_service), heartbeat_timer_(io_service) { } void Start(tcp::resolver::iterator endpoint_iter) { start_connect(endpoint_iter); deadline_.async_wait(boost::bind(&Connection::check_deadline, shared_from_this())); } private: void start_read() { deadline_.expires_from_now(boost::posix_time::seconds(30)); boost::asio::async_read_until(socket_, input_buffer_, 0x1f, boost::bind(&Connection::handle_read, shared_from_this(), _1)); } void handle_read(const boost::system::error_code& ec) { if (stopped_) return; if (!ec) { std::string line; std::istream is(&input_buffer_); std::getline(is, line); if (!line.empty()) { std::cout << "Received: " << line << "\n"; } start_read(); } else { // THIS IS WHERE THE ERROR IS LOGGED std::cout << "Error on receive: " << ec.message() << "\n"; Stop(); } } void check_deadline() { if (stopped_) return; if (deadline_.expires_at() <= deadline_timer::traits_type::now()) { socket_.close(); deadline_.expires_at(boost::posix_time::pos_infin); } deadline_.async_wait(boost::bind(&Connection::check_deadline, shared_from_this())); } }; 
3
  • 3
    Have you considered the effect of the deadline_ timer, which is set to 30 seconds in the start_read method? Commented Sep 2, 2019 at 6:37
  • @kenba Nope, I didn't even realize that there was a 30 second timeout on reads. Problem came when I changed the code for the "ping" to the server so it was only sent out once, then after the server's initial response nothing was read for 30 seconds so it closed the socket. Thanks a bunch! Commented Sep 2, 2019 at 7:37
  • @FranklinBarnett please answer your own question and accept it so that it doesn't show up as unanswered. Commented Sep 7, 2019 at 12:03

1 Answer 1

0

The issue turned out to be on the server's end. The server wasn't sending the "pong" response to the client's ping properly, so the async_read_until() call never finished and consequently never reset the deadline timer.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.