boost::asio::ip::tcp::socket is connected?

后端 未结 4 816
野趣味
野趣味 2020-12-23 22:16

I want to verify the connection status before performing read/write operations.

Is there a way to make an isConnect() method?

I saw this, but it seems \"ugly

4条回答
  •  北海茫月
    2020-12-23 23:00

    If you are sure that the remote socket has not sent anything (e.g. because you haven't sent a request to it yet), then you can set your local socket to a non blocking mode and try to read one or more bytes from it.

    Given that the server hasn't sent anything, you'll either get a asio::error::would_block or some other error. If former, your local socket has not yet detected a disconnection. If latter, your socket has been closed.

    Here is an example code:

    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    using namespace boost;
    using tcp = asio::ip::tcp;
    
    template
    void async_sleep(asio::io_service& ios, Duration d, asio::yield_context yield)
    {
      auto timer = asio::steady_timer(ios);
      timer.expires_from_now(d);
      timer.async_wait(yield);
    }
    
    int main()
    {
      asio::io_service ios;
      tcp::acceptor acceptor(ios, tcp::endpoint(tcp::v4(), 0));
    
      boost::asio::spawn(ios, [&](boost::asio::yield_context yield) {
        tcp::socket s(ios);
        acceptor.async_accept(s, yield);
        // Keep the socket from going out of scope for 5 seconds.
        async_sleep(ios, chrono::seconds(5), yield);
      });
    
      boost::asio::spawn(ios, [&](boost::asio::yield_context yield) {
        tcp::socket s(ios);
        s.async_connect(acceptor.local_endpoint(), yield);
    
        // This is essential to make the `read_some` function not block.
        s.non_blocking(true);
    
        while (true) {
          system::error_code ec;
          char c;
          // Unfortunately, this only works when the buffer has non
          // zero size (tested on Ubuntu 16.04).
          s.read_some(asio::mutable_buffer(&c, 1), ec);
          if (ec && ec != asio::error::would_block) break;
          cerr << "Socket is still connected" << endl;
          async_sleep(ios, chrono::seconds(1), yield);
        }
    
        cerr << "Socket is closed" << endl;
      });
    
      ios.run();
    }
    

    And the output:

    Socket is still connected
    Socket is still connected
    Socket is still connected
    Socket is still connected
    Socket is still connected
    Socket is closed
    

    Tested on:

    Ubuntu: 16.04
    Kernel: 4.15.0-36-generic
    Boost: 1.67

    Though, I don't know whether or not this behavior depends on any of those versions.

提交回复
热议问题