【问题标题】:remote_endpoint: Transport endpoint is not connectedremote_endpoint:传输端点未连接
【发布时间】:2014-03-16 01:40:27
【问题描述】:

Linux 上的io_service:run 发出异常。

这就是发生的事情。我使用 Boost.Asio 实现了简单的异步回显服务器。它是单线程的,一切都是异步的,也就是说我只使用异步版本的接受、发送和接收函数。当客户端没有正常断开连接(例如它崩溃)时,服务器的事件循环抛出 boost::system::system_error 异常 remote_endpoint: Transport endpoint is not connected。为什么会发生以及如何处理?是由 SIGPIPE 信号引起的吗?如果是这样,保持服务器运行的最佳方法是什么?处理异常还是处理信号?

【问题讨论】:

    标签: c++ linux boost-asio


    【解决方案1】:

    该异常表明调用了basic_stream_socket::remote_endpoint() 的抛出版本,其中对getpeername() 的底层调用返回了ENOTCONN 错误。根据effect of exceptions thrown from handlers 文档,处理程序中抛出的异常允许通过抛出线程的run()run_one()poll()poll_one() 调用向上传播。

    要解决此问题,请考虑:

    • 调用basic_stream_socket::remote_endpoint()的非抛出版本,并适当处理错误:

      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.
      }
      
    • try/catch 块内调用run()。文档中提到了以下代码:

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

      使用这种方法,线程可以重新调用run(),而无需在io_service 上调用reset()

    【讨论】:

    • 调用非抛出版本的函数不是解决问题的方法。解决问题首先要找出为什么会出现“remote_endpoint: Transport endpoint is not connected”异常。
    猜你喜欢
    • 2019-11-02
    • 2018-11-06
    • 2012-12-30
    • 2019-03-15
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多