Question

Exception is emitted from io_service:run on Linux.

This is what happens. I implemented simple asynchronous echo server using Boost.Asio. It is single threaded and everything is asynchronous, that is I use only asynchronous versions of accept, send and receive functions. When a client doesn't disconnect gracefully (e.g. it crashes) server's event loop throws boost::system::system_error exception remote_endpoint: Transport endpoint is not connected. Why it happens an how to deal with it? Is it caused by SIGPIPE signal? If so, what is the best way to keep the server running? Handle exception or handle signal?

Was it helpful?

Solution

The exception indicates that the throwing version of basic_stream_socket::remote_endpoint() was invoked, where in the underlying call to getpeername() returned with an error of ENOTCONN. Per the effect of exceptions thrown from handlers documentation, exceptions thrown within a handler are permitted to propagate up through the throwing thread's invocation of run(), run_one(), poll(), or poll_one().

To resolve this, consider either:

  • Invoking the non-throwing version of basic_stream_socket::remote_endpoint(), and handle the error appropriately:

    boost::system::error_code ec;
    boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
    if (ec)
    {
      // An error occurred.  Stop the asynchronous call chain for
      // this connection.
    }
    
  • Invoke run() from within a try/catch block. The following code is mentioned in the documentation:

    boost::asio::io_service io_service;
    ...
    for (;;)
    {
      try
      {
        io_service.run();
        break; // run() exited normally
      }
      catch (my_exception& e)
      {
        // Deal with exception as appropriate.
      }
    }
    

    With this approach, the thread may re-invoke run() without the need of invoking reset() on the io_service.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top