$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r63569 - trunk/libs/asio/example/timeouts
From: chris_at_[hidden]
Date: 2010-07-04 02:53:59
Author: chris_kohlhoff
Date: 2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
New Revision: 63569
URL: http://svn.boost.org/trac/boost/changeset/63569
Log:
Reworked timeout examples.
Added:
   trunk/libs/asio/example/timeouts/async_tcp_client.cpp   (contents, props changed)
   trunk/libs/asio/example/timeouts/blocking_tcp_client.cpp   (contents, props changed)
   trunk/libs/asio/example/timeouts/blocking_udp_client.cpp   (contents, props changed)
   trunk/libs/asio/example/timeouts/server.cpp   (contents, props changed)
Removed:
   trunk/libs/asio/example/timeouts/accept_timeout.cpp
   trunk/libs/asio/example/timeouts/connect_timeout.cpp
   trunk/libs/asio/example/timeouts/datagram_receive_timeout.cpp
   trunk/libs/asio/example/timeouts/stream_receive_timeout.cpp
Text files modified: 
   trunk/libs/asio/example/timeouts/Jamfile    |    16 ++++++++--------                        
   trunk/libs/asio/example/timeouts/Jamfile.v2 |     8 ++++----                                
   2 files changed, 12 insertions(+), 12 deletions(-)
Modified: trunk/libs/asio/example/timeouts/Jamfile
==============================================================================
--- trunk/libs/asio/example/timeouts/Jamfile	(original)
+++ trunk/libs/asio/example/timeouts/Jamfile	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
@@ -32,22 +32,22 @@
     $(SOCKET_LIBS)
   ;
 
-exe accept_timeout
+exe async_tcp_client
   : <template>asio_timeouts_example
-    accept_timeout.cpp
+    async_tcp_client.cpp
   ;
 
-exe connect_timeout
+exe blocking_tcp_client
   : <template>asio_timeouts_example
-    connect_timeout.cpp
+    blocking_tcp_client.cpp
   ;
 
-exe datagram_receive_timeout
+exe blocking_udp_client
   : <template>asio_timeouts_example
-    datagram_receive_timeout.cpp
+    blocking_udp_client.cpp
   ;
 
-exe stream_receive_timeout
+exe server
   : <template>asio_timeouts_example
-    stream_receive_timeout.cpp
+    server.cpp
   ;
Modified: trunk/libs/asio/example/timeouts/Jamfile.v2
==============================================================================
--- trunk/libs/asio/example/timeouts/Jamfile.v2	(original)
+++ trunk/libs/asio/example/timeouts/Jamfile.v2	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
@@ -37,7 +37,7 @@
     <os>HPUX:<library>ipv6
   ;
 
-exe accept_timeout : accept_timeout.cpp ;
-exe connect_timeout : connect_timeout.cpp ;
-exe datagram_receive_timeout : datagram_receive_timeout.cpp ;
-exe stream_receive_timeout : stream_receive_timeout.cpp ;
+exe async_tcp_client : async_tcp_client.cpp ;
+exe blocking_tcp_client : blocking_tcp_client.cpp ;
+exe blocking_udp_client : blocking_udp_client.cpp ;
+exe server : server.cpp ;
Deleted: trunk/libs/asio/example/timeouts/accept_timeout.cpp
==============================================================================
--- trunk/libs/asio/example/timeouts/accept_timeout.cpp	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
+++ (empty file)
@@ -1,74 +0,0 @@
-//
-// accept_timeout.cpp
-// ~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <boost/asio.hpp>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <iostream>
-
-using namespace boost::asio;
-using boost::asio::ip::tcp;
-
-class accept_handler
-{
-public:
-  accept_handler(io_service& ios)
-    : io_service_(ios),
-      timer_(ios),
-      acceptor_(ios, tcp::endpoint(tcp::v4(), 32123)),
-      socket_(ios)
-  {
-    acceptor_.async_accept(socket_,
-        boost::bind(&accept_handler::handle_accept, this,
-          boost::asio::placeholders::error));
-
-    timer_.expires_from_now(boost::posix_time::seconds(5));
-    timer_.async_wait(boost::bind(&accept_handler::close, this));
-  }
-
-  void handle_accept(const boost::system::error_code& err)
-  {
-    if (err)
-    {
-      std::cout << "Accept error: " << err.message() << "\n";
-    }
-    else
-    {
-      std::cout << "Successful accept\n";
-    }
-  }
-
-  void close()
-  {
-    acceptor_.close();
-  }
-
-private:
-  io_service& io_service_;
-  deadline_timer timer_;
-  tcp::acceptor acceptor_;
-  tcp::socket socket_;
-};
-
-int main()
-{
-  try
-  {
-    io_service ios;
-    accept_handler ah(ios);
-    ios.run();
-  }
-  catch (std::exception& e)
-  {
-    std::cerr << "Exception: " << e.what() << "\n";
-  }
-
-  return 0;
-}
Added: trunk/libs/asio/example/timeouts/async_tcp_client.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/example/timeouts/async_tcp_client.cpp	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
@@ -0,0 +1,305 @@
+//
+// async_tcp_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/asio/deadline_timer.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/read_until.hpp>
+#include <boost/asio/streambuf.hpp>
+#include <boost/asio/write.hpp>
+#include <boost/bind.hpp>
+#include <iostream>
+
+using boost::asio::deadline_timer;
+using boost::asio::ip::tcp;
+
+//
+// This class manages socket timeouts by applying the concept of a deadline.
+// Some asynchronous operations are given deadlines by which they must complete.
+// Deadlines are enforced by an "actor" that persists for the lifetime of the
+// client object:
+//
+//  +----------------+
+//  |                |
+//  | check_deadline |<---+
+//  |                |    |
+//  +----------------+    | async_wait()
+//              |         |
+//              +---------+
+//
+// If the deadline actor determines that the deadline has expired, the socket
+// is closed and any outstanding operations are consequently cancelled.
+//
+// Connection establishment involves trying each endpoint in turn until a
+// connection is successful, or the available endpoints are exhausted. If the
+// deadline actor closes the socket, the connect actor is woken up and moves to
+// the next endpoint.
+//
+//  +---------------+
+//  |               |
+//  | start_connect |<---+
+//  |               |    |
+//  +---------------+    |
+//           |           |
+//  async_-  |    +----------------+
+// connect() |    |                |
+//           +--->| handle_connect |
+//                |                |
+//                +----------------+
+//                          :
+// Once a connection is     :
+// made, the connect        :
+// actor forks in two -     :
+//                          :
+// an actor for reading     :       and an actor for
+// inbound messages:        :       sending heartbeats:
+//                          :
+//  +------------+          :          +-------------+
+//  |            |<- - - - -+- - - - ->|             |
+//  | start_read |                     | start_write |<---+
+//  |            |<---+                |             |    |
+//  +------------+    |                +-------------+    | async_wait()
+//          |         |                        |          |
+//  async_- |    +-------------+       async_- |    +--------------+
+//   read_- |    |             |       write() |    |              |
+//  until() +--->| handle_read |               +--->| handle_write |
+//               |             |                    |              |
+//               +-------------+                    +--------------+
+//
+// The input actor reads messages from the socket, where messages are delimited
+// by the newline character. The deadline for a complete message is 30 seconds.
+//
+// The heartbeat actor sends a heartbeat (a message that consists of a single
+// newline character) every 10 seconds. In this example, no deadline is applied
+// message sending.
+//
+class client
+{
+public:
+  client(boost::asio::io_service& io_service)
+    : stopped_(false),
+      socket_(io_service),
+      deadline_(io_service),
+      heartbeat_timer_(io_service)
+  {
+  }
+
+  // Called by the user of the client class to initiate the connection process.
+  // The endpoint iterator will have been obtained using a tcp::resolver.
+  void start(tcp::resolver::iterator endpoint_iter)
+  {
+    // Start the connect actor.
+    start_connect(endpoint_iter);
+
+    // Start the deadline actor. You will note that we're not setting any
+    // particular deadline here. Instead, the connect and input actors will
+    // update the deadline prior to each asynchronous operation.
+    deadline_.async_wait(boost::bind(&client::check_deadline, this));
+  }
+
+  // This function terminates all the actors to shut down the connection. It
+  // may be called by the user of the client class, or by the class itself in
+  // response to graceful termination or an unrecoverable error.
+  void stop()
+  {
+    stopped_ = true;
+    socket_.close();
+    deadline_.cancel();
+    heartbeat_timer_.cancel();
+  }
+
+private:
+  void start_connect(tcp::resolver::iterator endpoint_iter)
+  {
+    if (endpoint_iter != tcp::resolver::iterator())
+    {
+      std::cout << "Trying " << endpoint_iter->endpoint() << "...\n";
+
+      // Set a deadline for the connect operation.
+      deadline_.expires_from_now(boost::posix_time::seconds(60));
+
+      // Start the asynchronous connect operation.
+      socket_.async_connect(endpoint_iter->endpoint(),
+          boost::bind(&client::handle_connect,
+            this, _1, endpoint_iter));
+    }
+    else
+    {
+      // There are no more endpoints to try. Shut down the client.
+      stop();
+    }
+  }
+
+  void handle_connect(const boost::system::error_code& ec,
+      tcp::resolver::iterator endpoint_iter)
+  {
+    if (stopped_)
+      return;
+
+    // The async_connect() function automatically opens the socket at the start
+    // of the asynchronous operation. If the socket is closed at this time then
+    // the timeout handler must have run first.
+    if (!socket_.is_open())
+    {
+      std::cout << "Connect timed out\n";
+
+      // Try the next available endpoint.
+      start_connect(++endpoint_iter);
+    }
+
+    // Check if the connect operation failed before the deadline expired.
+    else if (ec)
+    {
+      std::cout << "Connect error: " << ec.message() << "\n";
+
+      // We need to close the socket used in the previous connection attempt
+      // before starting a new one.
+      socket_.close();
+
+      // Try the next available endpoint.
+      start_connect(++endpoint_iter);
+    }
+
+    // Otherwise we have successfully established a connection.
+    else
+    {
+      std::cout << "Connected to " << endpoint_iter->endpoint() << "\n";
+
+      // Start the input actor.
+      start_read();
+
+      // Start the heartbeat actor.
+      start_write();
+    }
+  }
+
+  void start_read()
+  {
+    // Set a deadline for the read operation.
+    deadline_.expires_from_now(boost::posix_time::seconds(30));
+
+    // Start an asynchronous operation to read a newline-delimited message.
+    boost::asio::async_read_until(socket_, input_buffer_, '\n',
+        boost::bind(&client::handle_read, this, _1));
+  }
+
+  void handle_read(const boost::system::error_code& ec)
+  {
+    if (stopped_)
+      return;
+
+    if (!ec)
+    {
+      // Extract the newline-delimited message from the buffer.
+      std::string line;
+      std::istream is(&input_buffer_);
+      std::getline(is, line);
+
+      // Empty messages are heartbeats and so ignored.
+      if (!line.empty())
+      {
+        std::cout << "Received: " << line << "\n";
+      }
+
+      start_read();
+    }
+    else
+    {
+      std::cout << "Error on receive: " << ec.message() << "\n";
+
+      stop();
+    }
+  }
+
+  void start_write()
+  {
+    if (stopped_)
+      return;
+
+    // Start an asynchronous operation to send a heartbeat message.
+    boost::asio::async_write(socket_, boost::asio::buffer("\n", 1),
+        boost::bind(&client::handle_write, this, _1));
+  }
+
+  void handle_write(const boost::system::error_code& ec)
+  {
+    if (stopped_)
+      return;
+
+    if (!ec)
+    {
+      // Wait 10 seconds before sending the next heartbeat.
+      heartbeat_timer_.expires_from_now(boost::posix_time::seconds(10));
+      heartbeat_timer_.async_wait(boost::bind(&client::start_write, this));
+    }
+    else
+    {
+      std::cout << "Error on heartbeat: " << ec.message() << "\n";
+
+      stop();
+    }
+  }
+
+  void check_deadline()
+  {
+    if (stopped_)
+      return;
+
+    // Check whether the deadline has passed. We compare the deadline against
+    // the current time since a new asynchronous operation may have moved the
+    // deadline before this actor had a chance to run.
+    if (deadline_.expires_at() <= deadline_timer::traits_type::now())
+    {
+      // The deadline has passed. The socket is closed so that any outstanding
+      // asynchronous operations are cancelled.
+      socket_.close();
+
+      // There is no longer an active deadline. The expiry is set to positive
+      // infinity so that the actor takes no action until a new deadline is set.
+      deadline_.expires_at(boost::posix_time::pos_infin);
+    }
+
+    // Put the actor back to sleep.
+    deadline_.async_wait(boost::bind(&client::check_deadline, this));
+  }
+
+private:
+  bool stopped_;
+  tcp::socket socket_;
+  boost::asio::streambuf input_buffer_;
+  deadline_timer deadline_;
+  deadline_timer heartbeat_timer_;
+};
+
+int main(int argc, char* argv[])
+{
+  try
+  {
+    if (argc != 3)
+    {
+      std::cerr << "Usage: client <host> <port>\n";
+      return 1;
+    }
+
+    boost::asio::io_service io_service;
+    tcp::resolver r(io_service);
+    client c(io_service);
+
+    c.start(r.resolve(tcp::resolver::query(argv[1], argv[2])));
+
+    io_service.run();
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << "Exception: " << e.what() << "\n";
+  }
+
+  return 0;
+}
Added: trunk/libs/asio/example/timeouts/blocking_tcp_client.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/example/timeouts/blocking_tcp_client.cpp	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
@@ -0,0 +1,250 @@
+//
+// blocking_tcp_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/asio/deadline_timer.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/read_until.hpp>
+#include <boost/asio/streambuf.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/asio/write.hpp>
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+
+using boost::asio::deadline_timer;
+using boost::asio::ip::tcp;
+using boost::lambda::bind;
+using boost::lambda::var;
+using boost::lambda::_1;
+
+//----------------------------------------------------------------------
+
+//
+// This class manages socket timeouts by applying the concept of a deadline.
+// Each asynchronous operation is given a deadline by which it must complete.
+// Deadlines are enforced by an "actor" that persists for the lifetime of the
+// client object:
+//
+//  +----------------+
+//  |                |     
+//  | check_deadline |<---+
+//  |                |    |
+//  +----------------+    | async_wait()
+//              |         |
+//              +---------+
+//
+// If the actor determines that the deadline has expired, the socket is closed
+// and any outstanding operations are consequently cancelled. The socket
+// operations themselves use boost::lambda function objects as completion
+// handlers. For a given socket operation, the client object runs the
+// io_service to block thread execution until the actor completes.
+//
+class client
+{
+public:
+  client()
+    : socket_(io_service_),
+      deadline_(io_service_)
+  {
+    // No deadline is required until the first socket operation is started. We
+    // set the deadline to positive infinity so that the actor takes no action
+    // until a specific deadline is set.
+    deadline_.expires_at(boost::posix_time::pos_infin);
+
+    // Start the persistent actor that checks for deadline expiry.
+    check_deadline();
+  }
+
+  void connect(const std::string& host, const std::string& service,
+      boost::posix_time::time_duration timeout)
+  {
+    // Resolve the host name and service to a list of endpoints.
+    tcp::resolver::query query(host, service);
+    tcp::resolver::iterator iter = tcp::resolver(io_service_).resolve(query);
+
+    // Set a deadline for the asynchronous operation. The host name may resolve
+    // to multiple endpoints, and this function tries to connect to each one in
+    // turn. Setting the deadline here means it applies to the entire sequence.
+    deadline_.expires_from_now(timeout);
+
+    boost::system::error_code ec;
+
+    for (; iter != tcp::resolver::iterator(); ++iter)
+    {
+      // We may have an open socket from a previous connection attempt. This
+      // socket cannot be reused, so we must close it before trying to connect
+      // again.
+      socket_.close();
+
+      // Set up the variable that receives the result of the asynchronous
+      // operation. The error code is set to would_block to signal that the
+      // operation is incomplete. Asio guarantees that its asynchronous
+      // operations will never fail with would_block, so any other value in
+      // ec indicates completion.
+      ec = boost::asio::error::would_block;
+
+      // Start the asynchronous operation itself. The boost::lambda function
+      // object is used as a callback and will update the ec variable when the
+      // operation completes. The blocking_udp_client.cpp example shows how you
+      // can use boost::bind rather than boost::lambda.
+      socket_.async_connect(iter->endpoint(), var(ec) = _1);
+
+      // Block until the asynchronous operation has completed.
+      do io_service_.run_one(); while (ec == boost::asio::error::would_block);
+
+      // Determine whether a connection was successfully established. The
+      // deadline actor may have had a chance to run and close our socket, even
+      // though the connect operation notionally succeeded. Therefore we must
+      // check whether the socket is still open before deciding that the we
+      // were successful.
+      if (!ec && socket_.is_open())
+        return;
+    }
+
+    throw boost::system::system_error(
+        ec ? ec : boost::asio::error::host_not_found);
+  }
+
+  std::string read_line(boost::posix_time::time_duration timeout)
+  {
+    // Set a deadline for the asynchronous operation. Since this function uses
+    // a composed operation (async_read_until), the deadline applies to the
+    // entire operation, rather than individual reads from the socket.
+    deadline_.expires_from_now(timeout);
+
+    // Set up the variable that receives the result of the asynchronous
+    // operation. The error code is set to would_block to signal that the
+    // operation is incomplete. Asio guarantees that its asynchronous
+    // operations will never fail with would_block, so any other value in
+    // ec indicates completion.
+    boost::system::error_code ec = boost::asio::error::would_block;
+
+    // Start the asynchronous operation itself. The boost::lambda function
+    // object is used as a callback and will update the ec variable when the
+    // operation completes. The blocking_udp_client.cpp example shows how you
+    // can use boost::bind rather than boost::lambda.
+    boost::asio::async_read_until(socket_, input_buffer_, '\n', var(ec) = _1);
+
+    // Block until the asynchronous operation has completed.
+    do io_service_.run_one(); while (ec == boost::asio::error::would_block);
+
+    if (ec)
+      throw boost::system::system_error(ec);
+
+    std::string line;
+    std::istream is(&input_buffer_);
+    std::getline(is, line);
+    return line;
+  }
+
+  void write_line(const std::string& line,
+      boost::posix_time::time_duration timeout)
+  {
+    std::string data = line + "\n";
+
+    // Set a deadline for the asynchronous operation. Since this function uses
+    // a composed operation (async_write), the deadline applies to the entire
+    // operation, rather than individual writes to the socket.
+    deadline_.expires_from_now(timeout);
+
+    // Set up the variable that receives the result of the asynchronous
+    // operation. The error code is set to would_block to signal that the
+    // operation is incomplete. Asio guarantees that its asynchronous
+    // operations will never fail with would_block, so any other value in
+    // ec indicates completion.
+    boost::system::error_code ec = boost::asio::error::would_block;
+
+    // Start the asynchronous operation itself. The boost::lambda function
+    // object is used as a callback and will update the ec variable when the
+    // operation completes. The blocking_udp_client.cpp example shows how you
+    // can use boost::bind rather than boost::lambda.
+    boost::asio::async_write(socket_, boost::asio::buffer(data), var(ec) = _1);
+
+    // Block until the asynchronous operation has completed.
+    do io_service_.run_one(); while (ec == boost::asio::error::would_block);
+
+    if (ec)
+      throw boost::system::system_error(ec);
+  }
+
+private:
+  void check_deadline()
+  {
+    // Check whether the deadline has passed. We compare the deadline against
+    // the current time since a new asynchronous operation may have moved the
+    // deadline before this actor had a chance to run.
+    if (deadline_.expires_at() <= deadline_timer::traits_type::now())
+    {
+      // The deadline has passed. The socket is closed so that any outstanding
+      // asynchronous operations are cancelled. This allows the blocked
+      // connect(), read_line() or write_line() functions to return.
+      socket_.close();
+
+      // There is no longer an active deadline. The expiry is set to positive
+      // infinity so that the actor takes no action until a new deadline is set.
+      deadline_.expires_at(boost::posix_time::pos_infin);
+    }
+
+    // Put the actor back to sleep.
+    deadline_.async_wait(bind(&client::check_deadline, this));
+  }
+
+  boost::asio::io_service io_service_;
+  tcp::socket socket_;
+  deadline_timer deadline_;
+  boost::asio::streambuf input_buffer_;
+};
+
+//----------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+  try
+  {
+    if (argc != 4)
+    {
+      std::cerr << "Usage: blocking_tcp <host> <port> <message>\n";
+      return 1;
+    }
+
+    client c;
+    c.connect(argv[1], argv[2], boost::posix_time::seconds(10));
+
+    boost::posix_time::ptime time_sent =
+      boost::posix_time::microsec_clock::universal_time();
+
+    c.write_line(argv[3], boost::posix_time::seconds(10));
+
+    for (;;)
+    {
+      std::string line = c.read_line(boost::posix_time::seconds(10));
+
+      // Keep going until we get back the line that was sent.
+      if (line == argv[3])
+        break;
+    }
+
+    boost::posix_time::ptime time_received =
+      boost::posix_time::microsec_clock::universal_time();
+
+    std::cout << "Round trip time: ";
+    std::cout << (time_received - time_sent).total_microseconds();
+    std::cout << " microseconds\n";
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << "Exception: " << e.what() << "\n";
+  }
+
+  return 0;
+}
Added: trunk/libs/asio/example/timeouts/blocking_udp_client.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/example/timeouts/blocking_udp_client.cpp	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
@@ -0,0 +1,182 @@
+//
+// blocking_udp_client.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/asio/deadline_timer.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/udp.hpp>
+#include <cstdlib>
+#include <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <iostream>
+
+using boost::asio::deadline_timer;
+using boost::asio::ip::udp;
+
+//----------------------------------------------------------------------
+
+//
+// This class manages socket timeouts by applying the concept of a deadline.
+// Each asynchronous operation is given a deadline by which it must complete.
+// Deadlines are enforced by an "actor" that persists for the lifetime of the
+// client object:
+//
+//  +----------------+
+//  |                |     
+//  | check_deadline |<---+
+//  |                |    |
+//  +----------------+    | async_wait()
+//              |         |
+//              +---------+
+//
+// If the actor determines that the deadline has expired, any outstanding
+// socket operations are cancelled. The socket operations themselves are
+// implemented as transient actors:
+//
+//   +---------------+
+//   |               |
+//   |    receive    |
+//   |               |
+//   +---------------+
+//           |
+//  async_-  |    +----------------+
+// receive() |    |                |
+//           +--->| handle_receive |
+//                |                |
+//                +----------------+
+//
+// The client object runs the io_service to block thread execution until the
+// actor completes.
+//
+class client
+{
+public:
+  client(const udp::endpoint& listen_endpoint)
+    : socket_(io_service_, listen_endpoint),
+      deadline_(io_service_)
+  {
+    // No deadline is required until the first socket operation is started. We
+    // set the deadline to positive infinity so that the actor takes no action
+    // until a specific deadline is set.
+    deadline_.expires_at(boost::posix_time::pos_infin);
+
+    // Start the persistent actor that checks for deadline expiry.
+    check_deadline();
+  }
+
+  std::size_t receive(const boost::asio::mutable_buffer& buffer,
+      boost::posix_time::time_duration timeout, boost::system::error_code& ec)
+  {
+    // Set a deadline for the asynchronous operation.
+    deadline_.expires_from_now(timeout);
+
+    // Set up the variables that receive the result of the asynchronous
+    // operation. The error code is set to would_block to signal that the
+    // operation is incomplete. Asio guarantees that its asynchronous
+    // operations will never fail with would_block, so any other value in
+    // ec indicates completion.
+    ec = boost::asio::error::would_block;
+    std::size_t length = 0;
+
+    // Start the asynchronous operation itself. The handle_receive function
+    // used as a callback will update the ec and length variables.
+    socket_.async_receive(boost::asio::buffer(buffer),
+        boost::bind(&client::handle_receive, _1, _2, &ec, &length));
+
+    // Block until the asynchronous operation has completed.
+    do io_service_.run_one(); while (ec == boost::asio::error::would_block);
+
+    return length;
+  }
+
+private:
+  void check_deadline()
+  {
+    // Check whether the deadline has passed. We compare the deadline against
+    // the current time since a new asynchronous operation may have moved the
+    // deadline before this actor had a chance to run.
+    if (deadline_.expires_at() <= deadline_timer::traits_type::now())
+    {
+      // The deadline has passed. The outstanding asynchronous operation needs
+      // to be cancelled so that the blocked receive() function will return.
+      //
+      // Please note that cancel() has portability issues on some versions of
+      // Microsoft Windows, and it may be necessary to use close() instead.
+      // Consult the documentation for cancel() for further information.
+      socket_.cancel();
+
+      // There is no longer an active deadline. The expiry is set to positive
+      // infinity so that the actor takes no action until a new deadline is set.
+      deadline_.expires_at(boost::posix_time::pos_infin);
+    }
+
+    // Put the actor back to sleep.
+    deadline_.async_wait(boost::bind(&client::check_deadline, this));
+  }
+
+  static void handle_receive(
+      const boost::system::error_code& ec, std::size_t length,
+      boost::system::error_code* out_ec, std::size_t* out_length)
+  {
+    *out_ec = ec;
+    *out_length = length;
+  }
+
+private:
+  boost::asio::io_service io_service_;
+  udp::socket socket_;
+  deadline_timer deadline_;
+};
+
+//----------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+  try
+  {
+    using namespace std; // For atoi.
+
+    if (argc != 3)
+    {
+      std::cerr << "Usage: blocking_udp_timeout <listen_addr> <listen_port>\n";
+      return 1;
+    }
+
+    udp::endpoint listen_endpoint(
+        boost::asio::ip::address::from_string(argv[1]),
+        std::atoi(argv[2]));
+
+    client c(listen_endpoint);
+
+    for (;;)
+    {
+      char data[1024];
+      boost::system::error_code ec;
+      std::size_t n = c.receive(boost::asio::buffer(data),
+          boost::posix_time::seconds(10), ec);
+
+      if (ec)
+      {
+        std::cout << "Receive error: " << ec.message() << "\n"; 
+      }
+      else
+      {
+        std::cout << "Received: ";
+        std::cout.write(data, n);
+        std::cout << "\n";
+      }
+    }
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << "Exception: " << e.what() << "\n";
+  }
+
+  return 0;
+}
Deleted: trunk/libs/asio/example/timeouts/connect_timeout.cpp
==============================================================================
--- trunk/libs/asio/example/timeouts/connect_timeout.cpp	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
+++ (empty file)
@@ -1,85 +0,0 @@
-//
-// connect_timeout.cpp
-// ~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <boost/asio.hpp>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <iostream>
-
-using namespace boost::asio;
-using boost::asio::ip::tcp;
-
-class connect_handler
-{
-public:
-  connect_handler(io_service& ios)
-    : io_service_(ios),
-      timer_(ios),
-      socket_(ios)
-  {
-    socket_.async_connect(
-        tcp::endpoint(boost::asio::ip::address_v4::loopback(), 32123),
-        boost::bind(&connect_handler::handle_connect, this,
-          boost::asio::placeholders::error));
-
-    timer_.expires_from_now(boost::posix_time::seconds(5));
-    timer_.async_wait(boost::bind(&connect_handler::close, this));
-  }
-
-  void handle_connect(const boost::system::error_code& err)
-  {
-    if (err)
-    {
-      std::cout << "Connect error: " << err.message() << "\n";
-    }
-    else
-    {
-      std::cout << "Successful connection\n";
-    }
-  }
-
-  void close()
-  {
-    socket_.close();
-  }
-
-private:
-  io_service& io_service_;
-  deadline_timer timer_;
-  tcp::socket socket_;
-};
-
-int main()
-{
-  try
-  {
-    io_service ios;
-    tcp::acceptor a(ios, tcp::endpoint(tcp::v4(), 32123), 1);
-
-    // Make lots of connections so that at least some of them will block.
-    connect_handler ch1(ios);
-    connect_handler ch2(ios);
-    connect_handler ch3(ios);
-    connect_handler ch4(ios);
-    connect_handler ch5(ios);
-    connect_handler ch6(ios);
-    connect_handler ch7(ios);
-    connect_handler ch8(ios);
-    connect_handler ch9(ios);
-
-    ios.run();
-  }
-  catch (std::exception& e)
-  {
-    std::cerr << "Exception: " << e.what() << "\n";
-  }
-
-  return 0;
-}
Deleted: trunk/libs/asio/example/timeouts/datagram_receive_timeout.cpp
==============================================================================
--- trunk/libs/asio/example/timeouts/datagram_receive_timeout.cpp	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
+++ (empty file)
@@ -1,78 +0,0 @@
-//
-// datagram_receive_timeout.cpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <boost/asio.hpp>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <iostream>
-
-using namespace boost::asio;
-using boost::asio::ip::udp;
-
-class datagram_handler
-{
-public:
-  datagram_handler(io_service& ios)
-    : io_service_(ios),
-      timer_(ios),
-      socket_(ios, udp::endpoint(udp::v4(), 32124))
-  {
-    socket_.async_receive_from(
-        boost::asio::buffer(data_, max_length), sender_endpoint_,
-        boost::bind(&datagram_handler::handle_receive_from, this,
-          boost::asio::placeholders::error,
-          boost::asio::placeholders::bytes_transferred));
-
-    timer_.expires_from_now(boost::posix_time::seconds(5));
-    timer_.async_wait(boost::bind(&datagram_handler::close, this));
-  }
-
-  void handle_receive_from(const boost::system::error_code& err,
-      size_t /*length*/)
-  {
-    if (err)
-    {
-      std::cout << "Receive error: " << err.message() << "\n";
-    }
-    else
-    {
-      std::cout << "Successful receive\n";
-    }
-  }
-
-  void close()
-  {
-    socket_.close();
-  }
-
-private:
-  io_service& io_service_;
-  deadline_timer timer_;
-  udp::socket socket_;
-  udp::endpoint sender_endpoint_;
-  enum { max_length = 512 };
-  char data_[max_length];
-};
-
-int main()
-{
-  try
-  {
-    io_service ios;
-    datagram_handler dh(ios);
-    ios.run();
-  }
-  catch (std::exception& e)
-  {
-    std::cerr << "Exception: " << e.what() << "\n";
-  }
-
-  return 0;
-}
Added: trunk/libs/asio/example/timeouts/server.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/example/timeouts/server.cpp	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
@@ -0,0 +1,424 @@
+//
+// server.cpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <algorithm>
+#include <cstdlib>
+#include <deque>
+#include <iostream>
+#include <set>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/asio/deadline_timer.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ip/udp.hpp>
+#include <boost/asio/read_until.hpp>
+#include <boost/asio/streambuf.hpp>
+#include <boost/asio/write.hpp>
+
+using boost::asio::deadline_timer;
+using boost::asio::ip::tcp;
+using boost::asio::ip::udp;
+
+//----------------------------------------------------------------------
+
+class subscriber
+{
+public:
+  virtual ~subscriber() {}
+  virtual void deliver(const std::string& msg) = 0;
+};
+
+typedef boost::shared_ptr<subscriber> subscriber_ptr;
+
+//----------------------------------------------------------------------
+
+class channel
+{
+public:
+  void join(subscriber_ptr subscriber)
+  {
+    subscribers_.insert(subscriber);
+  }
+
+  void leave(subscriber_ptr subscriber)
+  {
+    subscribers_.erase(subscriber);
+  }
+
+  void deliver(const std::string& msg)
+  {
+    std::for_each(subscribers_.begin(), subscribers_.end(),
+        boost::bind(&subscriber::deliver, _1, boost::ref(msg)));
+  }
+
+private:
+  std::set<subscriber_ptr> subscribers_;
+};
+
+//----------------------------------------------------------------------
+
+//
+// This class manages socket timeouts by applying the concept of a deadline.
+// Some asynchronous operations are given deadlines by which they must complete.
+// Deadlines are enforced by two "actors" that persist for the lifetime of the
+// session object, one for input and one for output:
+//
+//  +----------------+                     +----------------+
+//  |                |                     |                |
+//  | check_deadline |<---+                | check_deadline |<---+
+//  |                |    | async_wait()   |                |    | async_wait()
+//  +----------------+    |  on input      +----------------+    |  on output
+//              |         |  deadline                  |         |  deadline
+//              +---------+                            +---------+
+//
+// If either deadline actor determines that the corresponding deadline has
+// expired, the socket is closed and any outstanding operations are cancelled.
+//
+// The input actor reads messages from the socket, where messages are delimited
+// by the newline character:
+//
+//  +------------+
+//  |            |
+//  | start_read |<---+
+//  |            |    |
+//  +------------+    |
+//          |         |
+//  async_- |    +-------------+
+//   read_- |    |             |
+//  until() +--->| handle_read |
+//               |             |
+//               +-------------+
+//
+// The deadline for receiving a complete message is 30 seconds. If a non-empty
+// message is received, it is delivered to all subscribers. If a heartbeat (a
+// message that consists of a single newline character) is received, a heartbeat
+// is enqueued for the client, provided there are no other messages waiting to
+// be sent.
+//
+// The output actor is responsible for sending messages to the client:
+//
+//  +--------------+
+//  |              |<---------------------+
+//  | await_output |                      |
+//  |              |<---+                 |
+//  +--------------+    |                 |
+//      |      |        | async_wait()    |
+//      |      +--------+                 |
+//      V                                 |
+//  +-------------+               +--------------+
+//  |             | async_write() |              |
+//  | start_write |-------------->| handle_write |
+//  |             |               |              |
+//  +-------------+               +--------------+
+//
+// The output actor first waits for an output message to be enqueued. It does
+// this by using a deadline_timer as an asynchronous condition variable. The
+// deadline_timer will be signalled whenever the output queue is non-empty.
+//
+// Once a message is available, it is sent to the client. The deadline for
+// sending a complete message is 30 seconds. After the message is successfully
+// sent, the output actor again waits for the output queue to become non-empty.
+//
+class tcp_session
+  : public subscriber,
+    public boost::enable_shared_from_this<tcp_session>
+{
+public:
+  tcp_session(boost::asio::io_service& io_service, channel& ch)
+    : channel_(ch),
+      socket_(io_service),
+      input_deadline_(io_service),
+      non_empty_output_queue_(io_service),
+      output_deadline_(io_service)
+  {
+    input_deadline_.expires_at(boost::posix_time::pos_infin);
+    output_deadline_.expires_at(boost::posix_time::pos_infin);
+
+    // The non_empty_output_queue_ deadline_timer is set to pos_infin whenever
+    // the output queue is empty. This ensures that the output actor stays
+    // asleep until a message is put into the queue.
+    non_empty_output_queue_.expires_at(boost::posix_time::pos_infin);
+  }
+
+  tcp::socket& socket()
+  {
+    return socket_;
+  }
+
+  // Called by the server object to initiate the four actors.
+  void start()
+  {
+    channel_.join(shared_from_this());
+
+    start_read();
+
+    input_deadline_.async_wait(
+        boost::bind(&tcp_session::check_deadline,
+        shared_from_this(), &input_deadline_));
+
+    await_output();
+
+    output_deadline_.async_wait(
+        boost::bind(&tcp_session::check_deadline,
+        shared_from_this(), &output_deadline_));
+  }
+
+private:
+  void stop()
+  {
+    channel_.leave(shared_from_this());
+
+    socket_.close();
+    input_deadline_.cancel();
+    non_empty_output_queue_.cancel();
+    output_deadline_.cancel();
+  }
+
+  bool stopped() const
+  {
+    return !socket_.is_open();
+  }
+
+  void deliver(const std::string& msg)
+  {
+    output_queue_.push_back(msg + "\n");
+
+    // Signal that the output queue contains messages. Modifying the expiry
+    // will wake the output actor, if it is waiting on the timer.
+    non_empty_output_queue_.expires_at(boost::posix_time::neg_infin);
+  }
+
+  void start_read()
+  {
+    // Set a deadline for the read operation.
+    input_deadline_.expires_from_now(boost::posix_time::seconds(30));
+
+    // Start an asynchronous operation to read a newline-delimited message.
+    boost::asio::async_read_until(socket_, input_buffer_, '\n',
+        boost::bind(&tcp_session::handle_read, shared_from_this(), _1));
+  }
+
+  void handle_read(const boost::system::error_code& ec)
+  {
+    if (stopped())
+      return;
+
+    if (!ec)
+    {
+      // Extract the newline-delimited message from the buffer.
+      std::string msg;
+      std::istream is(&input_buffer_);
+      std::getline(is, msg);
+
+      if (!msg.empty())
+      {
+        channel_.deliver(msg);
+      }
+      else
+      {
+        // We received a heartbeat message from the client. If there's nothing
+        // else being sent or ready to be sent, send a heartbeat right back.
+        if (output_queue_.empty())
+        {
+          output_queue_.push_back("\n");
+
+          // Signal that the output queue contains messages. Modifying the
+          // expiry will wake the output actor, if it is waiting on the timer.
+          non_empty_output_queue_.expires_at(boost::posix_time::neg_infin);
+        }
+      }
+
+      start_read();
+    }
+    else
+    {
+      stop();
+    }
+  }
+
+  void await_output()
+  {
+    if (stopped())
+      return;
+
+    if (output_queue_.empty())
+    {
+      // There are no messages that are ready to be sent. The actor goes to
+      // sleep by waiting on the non_empty_output_queue_ timer. When a new
+      // message is added, the timer will be modified and the actor will wake.
+      non_empty_output_queue_.expires_at(boost::posix_time::pos_infin);
+      non_empty_output_queue_.async_wait(
+          boost::bind(&tcp_session::await_output, shared_from_this()));
+    }
+    else
+    {
+      start_write();
+    }
+  }
+
+  void start_write()
+  {
+    // Set a deadline for the write operation.
+    output_deadline_.expires_from_now(boost::posix_time::seconds(30));
+
+    // Start an asynchronous operation to send a message.
+    boost::asio::async_write(socket_,
+        boost::asio::buffer(output_queue_.front()),
+        boost::bind(&tcp_session::handle_write, shared_from_this(), _1));
+  }
+
+  void handle_write(const boost::system::error_code& ec)
+  {
+    if (stopped())
+      return;
+
+    if (!ec)
+    {
+      output_queue_.pop_front();
+
+      await_output();
+    }
+    else
+    {
+      stop();
+    }
+  }
+
+  void check_deadline(deadline_timer* deadline)
+  {
+    if (stopped())
+      return;
+
+    // Check whether the deadline has passed. We compare the deadline against
+    // the current time since a new asynchronous operation may have moved the
+    // deadline before this actor had a chance to run.
+    if (deadline->expires_at() <= deadline_timer::traits_type::now())
+    {
+      // The deadline has passed. Stop the session. The other actors will
+      // terminate as soon as possible.
+      stop();
+    }
+    else
+    {
+      // Put the actor back to sleep.
+      deadline->async_wait(
+          boost::bind(&tcp_session::check_deadline,
+          shared_from_this(), deadline));
+    }
+  }
+
+  channel& channel_;
+  tcp::socket socket_;
+  boost::asio::streambuf input_buffer_;
+  deadline_timer input_deadline_;
+  std::deque<std::string> output_queue_;
+  deadline_timer non_empty_output_queue_;
+  deadline_timer output_deadline_;
+};
+
+typedef boost::shared_ptr<tcp_session> tcp_session_ptr;
+
+//----------------------------------------------------------------------
+
+class udp_broadcaster
+  : public subscriber
+{
+public:
+  udp_broadcaster(boost::asio::io_service& io_service,
+      const udp::endpoint& broadcast_endpoint)
+    : socket_(io_service)
+  {
+    socket_.connect(broadcast_endpoint);
+  }
+
+private:
+  void deliver(const std::string& msg)
+  {
+    boost::system::error_code ignored_ec;
+    socket_.send(boost::asio::buffer(msg), 0, ignored_ec);
+  }
+
+  udp::socket socket_;
+};
+
+//----------------------------------------------------------------------
+
+class server
+{
+public:
+  server(boost::asio::io_service& io_service,
+      const tcp::endpoint& listen_endpoint,
+      const udp::endpoint& broadcast_endpoint)
+    : io_service_(io_service),
+      acceptor_(io_service, listen_endpoint)
+  {
+    subscriber_ptr bc(new udp_broadcaster(io_service_, broadcast_endpoint));
+    channel_.join(bc);
+
+    tcp_session_ptr new_session(new tcp_session(io_service_, channel_));
+
+    acceptor_.async_accept(new_session->socket(),
+        boost::bind(&server::handle_accept, this, new_session, _1));
+  }
+
+  void handle_accept(tcp_session_ptr session,
+      const boost::system::error_code& ec)
+  {
+    if (!ec)
+    {
+      session->start();
+
+      tcp_session_ptr new_session(new tcp_session(io_service_, channel_));
+
+      acceptor_.async_accept(new_session->socket(),
+          boost::bind(&server::handle_accept, this, new_session, _1));
+    }
+  }
+
+private:
+  boost::asio::io_service& io_service_;
+  tcp::acceptor acceptor_;
+  channel channel_;
+};
+
+//----------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+  try
+  {
+    using namespace std; // For atoi.
+
+    if (argc != 4)
+    {
+      std::cerr << "Usage: server <listen_port> <bcast_address> <bcast_port>\n";
+      return 1;
+    }
+
+    boost::asio::io_service io_service;
+
+    tcp::endpoint listen_endpoint(tcp::v4(), atoi(argv[1]));
+
+    udp::endpoint broadcast_endpoint(
+        boost::asio::ip::address::from_string(argv[2]), atoi(argv[3]));
+
+    server s(io_service, listen_endpoint, broadcast_endpoint);
+
+    io_service.run();
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << "Exception: " << e.what() << "\n";
+  }
+
+  return 0;
+}
Deleted: trunk/libs/asio/example/timeouts/stream_receive_timeout.cpp
==============================================================================
--- trunk/libs/asio/example/timeouts/stream_receive_timeout.cpp	2010-07-04 02:53:57 EDT (Sun, 04 Jul 2010)
+++ (empty file)
@@ -1,102 +0,0 @@
-//
-// stream_receive_timeout.cpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <boost/asio.hpp>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <iostream>
-
-using namespace boost::asio;
-using boost::asio::ip::tcp;
-
-class stream_handler
-{
-public:
-  stream_handler(io_service& ios)
-    : io_service_(ios),
-      timer_(ios),
-      acceptor_(ios, tcp::endpoint(tcp::v4(), 32123)),
-      socket_(ios)
-  {
-    acceptor_.async_accept(socket_,
-        boost::bind(&stream_handler::handle_accept, this,
-          boost::asio::placeholders::error));
-  }
-
-  void handle_accept(const boost::system::error_code& err)
-  {
-    if (err)
-    {
-      std::cout << "Accept error: " << err.message() << "\n";
-    }
-    else
-    {
-      std::cout << "Successful accept\n";
-
-      socket_.async_read_some(boost::asio::buffer(buf_, sizeof(buf_)),
-          boost::bind(&stream_handler::handle_recv, this,
-            boost::asio::placeholders::error));
-      timer_.expires_from_now(boost::posix_time::seconds(5));
-      timer_.async_wait(boost::bind(&stream_handler::close, this));
-    }
-  }
-
-  void handle_recv(const boost::system::error_code& err)
-  {
-    if (err)
-    {
-      std::cout << "Receive error: " << err.message() << "\n";
-    }
-    else
-    {
-      std::cout << "Successful receive\n";
-    }
-  }
-
-  void close()
-  {
-    socket_.close();
-  }
-
-private:
-  io_service& io_service_;
-  deadline_timer timer_;
-  tcp::acceptor acceptor_;
-  tcp::socket socket_;
-  char buf_[1024];
-};
-
-void connect_handler()
-{
-  std::cout << "Successful connect\n";
-}
-
-int main()
-{
-  try
-  {
-    io_service ios;
-
-    stream_handler sh(ios);
-
-    tcp::socket s(ios);
-    s.async_connect(
-        tcp::endpoint(boost::asio::ip::address_v4::loopback(), 32123),
-        boost::bind(connect_handler));
-
-    ios.run();
-  }
-  catch (std::exception& e)
-  {
-    std::cerr << "Exception: " << e.what() << "\n";
-  }
-
-  return 0;
-}