title: ASIO example code closing socket before it should
body: <p>I need a parallel synchronous TCP solution using ASIO. I'm trying to get the example code from these examples working: <a href="https://github.com/jvillasante/asio-network-programming-cookbook/tree/master/src" rel="nofollow noreferrer">https://github.com/jvillasante/asio-network-programming-cookbook/tree/master/src</a> (using the server in ch04: 02_Sync_parallel_tcp_server.cpp and the client in ch03: 01_Sync_tcp_client.cpp).</p>
  
  <p>The only thing I changed is the logging to append to text files.</p>
  
  <p>The problem is that while the server runs fine, the client dies after returning a single response from the server:</p>
  
  <pre><code>libc++abi.dylib: terminating with uncaught exception of type boost::exception_detail::clone_impl&lt;boost::exception_detail::error_info_injector&lt;boost::system::system_error&gt; &gt;: shutdown: Socket is not connected
  </code></pre>
  
  <p>Code for the server:</p>
  
  <pre><code>#include &lt;boost/asio.hpp&gt;
  #include &lt;atomic&gt;
  #include &lt;memory&gt;
  #include &lt;thread&gt;
  #include &lt;iostream&gt;
  #include &lt;fstream&gt;
  
  using namespace boost;
  
  class Service {
  public:
    Service() = default;
  
    void StartHandlingClient(std::shared_ptr&lt;asio::ip::tcp::socket&gt; sock) {
      std::thread th{[this, sock]() { HandleClient(sock); }};
      th.detach();
    }
  
  private:
    void HandleClient(std::shared_ptr&lt;asio::ip::tcp::socket&gt; sock) {
      try {
        asio::streambuf request;
        asio::read_until(*sock.get(), request, '\n');
  
        std::istream is(&amp;request);
        std::string line;
        std::getline(is, line);
  
        std::ofstream log("logfile2.txt", std::ios_base::app | std::ios_base::out);
        log &lt;&lt; "Request: " &lt;&lt; line &lt;&lt; "\n" &lt;&lt; std::flush;
  
        // Emulate request processing.
        int i = 0;
        while (i != 1000000) i++;
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
  
        // Sending response.
        std::string response = "Response\n";
        asio::write(*sock.get(), asio::buffer(response));
      } catch (std::system_error&amp; e) {
        std::ofstream log("logfile1.txt", std::ios_base::app | std::ios_base::out);
        log &lt;&lt; "Error occurred! Error code = " &lt;&lt; e.code().value() &lt;&lt; ". Message: " &lt;&lt; e.what() &lt;&lt; "\n" &lt;&lt; std::flush;
      }
  
      // Clean up
      delete this;
    }
  };
  
  class Acceptor {
  public:
    Acceptor(asio::io_service&amp; ios, unsigned short port_num)
    : m_ios{ios}, m_acceptor{m_ios, asio::ip::tcp::endpoint{asio::ip::address_v4::any(), port_num}} {
      m_acceptor.listen();
    }
  
    void Accept() {
      auto sock = std::make_shared&lt;asio::ip::tcp::socket&gt;(m_ios);
  
      m_acceptor.accept(*sock.get());
  
      (new Service)-&gt;StartHandlingClient(sock);
    }
  
  private:
    asio::io_service&amp; m_ios;
    asio::ip::tcp::acceptor m_acceptor;
  };
  
  class Server {
  public:
    Server() : m_stop{false} {}
  
    void Start(unsigned short port_num) {
      m_thread.reset(new std::thread([this, port_num]() { Run(port_num); }));
    }
  
    void Stop() {
      m_stop.store(true);
      m_thread-&gt;join();
    }
  
  private:
    void Run(unsigned short port_num) {
      Acceptor acc{m_ios, port_num};
  
      while (!m_stop.load()) {
        acc.Accept();
      }
    }
  
  private:
    std::unique_ptr&lt;std::thread&gt; m_thread;
    std::atomic&lt;bool&gt; m_stop;
    asio::io_service m_ios;
  };
  
  int main() {
    unsigned short port_num = 3333;
  
    try {
      Server srv;
      srv.Start(port_num);
  
      std::this_thread::sleep_for(std::chrono::seconds(60));
  
      srv.Stop();
    } catch (std::system_error&amp; e) {
        std::ofstream log("logfile1.txt", std::ios_base::app | std::ios_base::out);
        log &lt;&lt; "Error occurred! Error code = " &lt;&lt; e.code().value() &lt;&lt; ". Message: " &lt;&lt; e.what() &lt;&lt; "\n" &lt;&lt; std::flush;
    }
  
    return 0;
  }
  </code></pre>
  
  <p>Code for the client:</p>
  
  <pre><code>#include &lt;boost/asio.hpp&gt;
  #include &lt;iostream&gt;
  #include &lt;fstream&gt;
  
  using namespace boost;
  
  class SyncTCPClient {
  public:
    SyncTCPClient(const std::string&amp; raw_ip_address, unsigned short port_num)
    : m_ep(asio::ip::address::from_string(raw_ip_address), port_num), m_sock(m_ios) {
      m_sock.open(m_ep.protocol());
    }
    ~SyncTCPClient() { close(); }
  
    void connect() { m_sock.connect(m_ep); }
  
    std::string emulateLongComputationOp(unsigned int duration_sec) {
      std::string request = "EMULATE_LONG_COMP_OP " + std::to_string(duration_sec) + "\n";
      sendRequest(request);
      return receiveResponse();
    }
  
  private:
    void close() {
      if (m_sock.is_open()) {
        std::ofstream log("logfile1.txt", std::ios_base::app | std::ios_base::out);
        log &lt;&lt; "shutting down\n" &lt;&lt; std::flush;
        m_sock.shutdown(asio::ip::tcp::socket::shutdown_both);
        log &lt;&lt; "closing the socket\n" &lt;&lt; std::flush;
        m_sock.close();
        log &lt;&lt; "socket closed\n" &lt;&lt; std::flush;
      }
    }
  
    void sendRequest(const std::string&amp; request) { asio::write(m_sock, asio::buffer(request)); }
  
    std::string receiveResponse() {
      asio::streambuf buf;
      asio::read_until(m_sock, buf, '\n');
  
      std::istream input(&amp;buf);
      std::string response;
      std::getline(input, response);
  
      return response;
    }
  
  private:
    asio::io_service m_ios;
    asio::ip::tcp::endpoint m_ep;
    asio::ip::tcp::socket m_sock;
  };
  
  int main() {
    const std::string raw_ip_address = "127.0.0.1";
    const unsigned short port_num = 3333;
  
    try {
      SyncTCPClient client{raw_ip_address, port_num};
  
      // Sync connect.
      client.connect();
  
      std::cout &lt;&lt; "Sending request to the server...\n";
      std::string response = client.emulateLongComputationOp(10);
  
      std::cout &lt;&lt; "Response received: " &lt;&lt; response &lt;&lt; "\n";
    } catch (std::system_error&amp; e) {
        std::ofstream log("logfile1.txt", std::ios_base::app | std::ios_base::out);
        log &lt;&lt; "Error occurred! Error code = " &lt;&lt; e.code().value() &lt;&lt; ". Message: " &lt;&lt; e.what() &lt;&lt; "\n" &lt;&lt; std::flush;
      return e.code().value();
    }
  
    return 0;
  }
  </code></pre>