How to detect when a boost tcp socket disconnects

半腔热情 提交于 2019-11-28 21:29:40
kenba

A TCP socket disconnect is usually signalled in asio by an eof or a connection_reset. E.g.

  void async_receive(boost::system::error_code const& error,
                     size_t bytes_transferred)
  {
    if ((boost::asio::error::eof == error) ||
        (boost::asio::error::connection_reset == error))
    {
      // handle the disconnect.
    }
    else
    {
       // read the data 
    }
  }

I use boost::signals2 to signal the disconnect although you can always pass a pointer to a function to your socket class and then call that.

Be careful about your socket and callback lifetimes, see: boost-async-functions-and-shared-ptrs

There are many options, some of them are:

  1. As you store weak_ptr in container - it will not prolong lifetime of socket, so when your handler will get boost::asio::error::eof (or whatever), it will not do copy/move of shared_ptr, and socket will be deleted (if you don't have any others shared_ptrs to it). So, you can do something like: if(socket.expired()) clients_.erase(socket);

  2. Check error code in your handler - it will indicate when connection is closed. Using this info - you can call clients_.erase from handler itself.

Could you give an example of #2?

It will be something like:

socket->async_receive
(
    boost::asio::buffer(&(*header), sizeof(Header)), 0,
    [=, &clients_](const system::error_code& error, size_t bytes_transferred)
    {
        if(error) // or some specific code
        {
            clients_.erase(socket); // pseudocode
        }
        else
        {
            // continue, launch new operation, etc
        }
    }
);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!