00001 /* $Id: network_asio.hpp 54108 2012-05-06 19:18:05Z loonycyborg $ */ 00002 /* 00003 Copyright (C) 2011 - 2012 by Sergey Popov <loonycyborg@gmail.com> 00004 Part of the Battle for Wesnoth Project http://www.wesnoth.org/ 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY. 00012 00013 See the COPYING file for more details. 00014 */ 00015 00016 #ifndef NETWORK_ASIO_HPP_INCLUDED 00017 #define NETWORK_ASIO_HPP_INCLUDED 00018 00019 #ifdef _WIN32 00020 #define BOOST_ASIO_DISABLE_IOCP 00021 #ifdef INADDR_ANY 00022 #undef INADDR_ANY 00023 #endif 00024 #ifdef INADDR_BROADCAST 00025 #undef INADDR_BROADCAST 00026 #endif 00027 #ifdef INADDR_NONE 00028 #undef INADDR_NONE 00029 #endif 00030 #endif 00031 #include <boost/asio.hpp> 00032 #include <boost/optional.hpp> 00033 #include "exceptions.hpp" 00034 #include "config.hpp" 00035 00036 namespace network_asio { 00037 00038 struct error : public game::error 00039 { 00040 error(const boost::system::error_code& error) : game::error(error.message()) {} 00041 }; 00042 00043 /** A class that represents a TCP/IP connection. */ 00044 class connection 00045 { 00046 boost::asio::io_service io_service_; 00047 typedef boost::asio::ip::tcp::resolver resolver; 00048 resolver resolver_; 00049 00050 typedef boost::asio::ip::tcp::socket socket; 00051 socket socket_; 00052 00053 bool done_; 00054 00055 boost::asio::streambuf write_buf_; 00056 boost::asio::streambuf read_buf_; 00057 00058 void handle_resolve( 00059 const boost::system::error_code& ec, 00060 resolver::iterator iterator 00061 ); 00062 00063 void connect(resolver::iterator iterator); 00064 void handle_connect( 00065 const boost::system::error_code& ec, 00066 resolver::iterator iterator 00067 ); 00068 void handshake(); 00069 void handle_handshake( 00070 const boost::system::error_code& ec 00071 ); 00072 union { 00073 char binary[4]; 00074 boost::uint32_t num; 00075 } handshake_response_; 00076 00077 std::size_t is_write_complete( 00078 const boost::system::error_code& error, 00079 std::size_t bytes_transferred 00080 ); 00081 void handle_write( 00082 const boost::system::error_code& ec, 00083 std::size_t bytes_transferred 00084 ); 00085 std::size_t is_read_complete( 00086 const boost::system::error_code& error, 00087 std::size_t bytes_transferred 00088 ); 00089 void handle_read( 00090 const boost::system::error_code& ec, 00091 std::size_t bytes_transferred, 00092 config& response 00093 ); 00094 boost::uint32_t payload_size_; 00095 std::size_t bytes_to_write_; 00096 std::size_t bytes_written_; 00097 std::size_t bytes_to_read_; 00098 std::size_t bytes_read_; 00099 00100 public: 00101 /** 00102 * Constructor. 00103 * 00104 * @param host Name of the host to connect to 00105 * @param service Service identifier such as "80" or "http" 00106 */ 00107 connection(const std::string& host, const std::string& service); 00108 00109 void transfer(const config& request, config& response); 00110 00111 /** Handle all pending asynchonous events and return */ 00112 std::size_t poll() 00113 { 00114 try { 00115 return io_service_.poll(); 00116 } catch(const boost::system::system_error& err) { 00117 if(err.code() == boost::asio::error::operation_aborted) 00118 return 1; 00119 throw error(err.code()); 00120 } 00121 } 00122 /** Run asio's event loop 00123 * 00124 * Handle asynchronous events blocking until all asynchronous 00125 * operations have finished 00126 */ 00127 void run() { io_service_.run(); } 00128 00129 void cancel(); 00130 00131 /** True if connected and no high-level operation is in progress */ 00132 bool done() const { return done_; } 00133 00134 std::size_t bytes_to_write() const 00135 { 00136 return bytes_to_write_; 00137 } 00138 std::size_t bytes_written() const 00139 { 00140 return bytes_written_; 00141 } 00142 std::size_t bytes_to_read() const 00143 { 00144 return bytes_to_read_; 00145 } 00146 std::size_t bytes_read() const 00147 { 00148 return bytes_read_; 00149 } 00150 }; 00151 00152 } 00153 00154 #endif
| Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:07 for The Battle for Wesnoth | Gna! | Forum | Wiki | CIA | devdocs |