title: How do I cleanly reconnect a boost::socket following a disconnect?
body: <p>My client application uses a <code>boost::asio::ip::tcp::socket</code> to connect to a remote server.
  If the app loses connection to this server (e.g. due to the server crashing or being shutdown) I would like it to attempt a re-connect at regular intervals until it succeeds.</p>
  
  <p><strong>What do I need to do on the client-side to cleanly handle a disconnect, tidy up and then repeatedly attempt reconnects?</strong></p>
  
  <p>Currently the interesting bits of my code look something like this.  </p>
  
  <p>I <code>connect</code> like this:</p>
  
  <pre><code>bool MyClient::myconnect()
  {
      bool isConnected = false;
  
      // Attempt connection
      socket.connect(server_endpoint, errorcode);
  
      if (errorcode)
      {
          cerr &lt;&lt; "Connection failed: " &lt;&lt; errorcode.message() &lt;&lt; endl;
          mydisconnect();
      }
      else
      {
          isConnected = true;
  
          // Connected so setup async read for an incoming message.
          startReadMessage();
  
          // And start the io_service_thread
          io_service_thread = new boost::thread(
              boost::bind(&amp;MyClient::runIOService, this, boost::ref(io_service)));
      }
      return (isConnected)
  }
  </code></pre>
  
  <p>Where the <code>runIOServer()</code> method is just:</p>
  
  <pre><code>void MyClient::runIOService(boost::asio::io_service&amp; io_service)
  {
      size_t executedCount = io_service.run();
      cout &lt;&lt; "io_service: " &lt;&lt; executedCount &lt;&lt; " handlers executed." &lt;&lt; endl;
      io_service.reset();
  }
  </code></pre>
  
  <p>And if any of the async read handlers return an error then they just call this <code>disconnect</code> method:</p>
  
  <pre><code>void MyClient::mydisconnect(void)
  {
      boost::system::error_code errorcode;
  
      if (socket.is_open())
      {
          // Boost documentation recommends calling shutdown first
          // for "graceful" closing of socket.
          socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorcode);
          if (errorcode)
          {
              cerr &lt;&lt; "socket.shutdown error: " &lt;&lt; errorcode.message() &lt;&lt; endl;
          }
  
          socket.close(errorcode);
          if (errorcode)
          {
              cerr &lt;&lt; "socket.close error: " &lt;&lt; errorcode.message() &lt;&lt; endl;
          }    
  
          // Notify the observer we have disconnected
          myObserver-&gt;disconnected();            
      }
  </code></pre>
  
  <p>..which attempts to gracefully disconnect and then notifies an observer, which will start calling <code>connect()</code> at five second intervals until it gets reconnected.</p>
  
  <p><strong>Is there anything else I need to do?</strong></p>
  
  <p>Currently this does <em>seem</em> to work. If I kill the server that it is connected to I get the expected <code>"End of file"</code> error at my read handlers and <code>mydisconnect()</code> is called without any issues.   </p>
  
  <p>But when it then attempts to re-connect and fails I see it report <code>"socket.shutdown error: Invalid argument"</code>. Is this just because I am attempting to shutdown a socket that has no read/writes pending on it? Or is it something more?</p>