Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // file - Server.h
- class Server
- {
- public:
- explicit Server(const std::string &address,
- int port,
- std::size_t threadPoolSize);
- // run the io_service loop
- void run();
- // stop the server
- void stop();
- private:
- //handle async accept operation
- void handleAccept(const boost::system::error_code &e);
- // number of threads in thread pool
- std::size_t _threadPoolSize;
- // the io_service
- boost::asio::io_service _ioService;
- // acceptor to listen for incoming connections
- boost::asio::ip::tcp::acceptor _acceptor;
- std::string get_password()
- {
- return "password";
- }
- // ssl context
- boost::asio::ssl::context _context;
- ConnectionPtr _connection;
- };
- //////////////////////////////////////////////////////////////////////////
- // file - Server.cpp
- //////////////////////////////////////////////////////////////////////////
- Server::Server(const std::string& address,
- int port,
- std::size_t threadPoolSize)
- : _threadPoolSize(threadPoolSize),
- _acceptor(_ioService),
- _context(_ioService, boost::asio::ssl::context::sslv23),
- _connection()
- {
- try {
- DEBUG_2("Starting server on port: ", port);
- boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
- _acceptor.open(endpoint.protocol());
- _acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
- _acceptor.bind(endpoint);
- _acceptor.listen();
- _context.set_options(
- boost::asio::ssl::context::default_workarounds
- | boost::asio::ssl::context::no_sslv2
- | boost::asio::ssl::context::single_dh_use);
- _context.set_password_callback(boost::bind(&Server::get_password, this));
- _context.use_certificate_chain_file("./demoCA/cacert.pem");
- _context.use_private_key_file("./demoCA/private/cakey.pem",
- boost::asio::ssl::context::pem);
- // _context.use_tmp_dh_file("dh512.pem");
- _connection.reset(new CclConnection(_ioService, _context));
- _acceptor.async_accept(_connection->socket(),
- boost::bind(&Server::handleAccept,
- this,
- boost::asio::placeholders::error));
- }
- catch(std::exception& e)
- {
- STD_EXCEPTION_MESSAGE;
- throw;
- }
- }
- void Server::run()
- {
- // Create a pool of threads to run all of the io_services.
- std::vector<boost::shared_ptr<boost::thread> > threads;
- for (std::size_t i = 0; i < _threadPoolSize; ++i)
- {
- boost::shared_ptr<boost::thread>
- thread(new boost::thread(
- boost::bind(&boost::asio::io_service::run,
- &_ioService)
- )
- );
- threads.push_back(thread);
- }
- // Wait for all threads in the pool to exit.
- for (std::size_t i = 0; i < threads.size(); ++i)
- threads[i]->join();
- }
- void Server::stop()
- {
- _ioService.stop();
- }
- void Server::handleAccept(const boost::system::error_code& e)
- {
- if (!e)
- {
- _connection->handshake();
- _connection.reset(new CclConnection(_ioService, _context));
- _acceptor.async_accept(_connection->socket(),
- boost::bind(&Server::handleAccept,
- this,
- boost::asio::placeholders::error));
- }
- }
- ////////////////////////////////////////////////////////////
- // file - Connection.h
- ////////////////////////////////////////////////////////////
- #include <boost/asio.hpp>
- #include <boost/asio/ssl.hpp>
- #include <boost/shared_ptr.hpp>
- #include <boost/enable_shared_from_this.hpp>
- typedef boost::asio::ssl::stream< boost::asio::ip::tcp::socket >
- ssl_socket;
- class Connection
- : public boost::enable_shared_from_this<Connection>
- {
- public:
- explicit Connection(boost::asio::io_service& io_service,
- boost::asio::ssl::context& context);
- //get socket from the connection
- ssl_socket::lowest_layer_type& socket();
- // do an SSL handshake
- void handshake();
- //get socket from the connection
- boost::asio::io_service::strand& strand();
- // start first async operation
- void start();
- void sendResponse(const Response& response);
- void close();
- // get remote IP address for this connection
- std::string getIPAddress();
- private:
- void handleRead(const boost::system::error_code& e,
- std::size_t bytesTransferred);
- void handleWrite(const boost::system::error_code& e);
- boost::asio::io_service::strand _strand;
- ssl_socket _socket;
- void handleHandshake(const boost::system::error_code& e);
- boost::array<char, 8192> _buffer;
- };
- typedef boost::shared_ptr<Connection> ConnectionPtr;
- ///////////////////////////////////////////////////////////////
- // File - Connection.cpp
- ///////////////////////////////////////////////////////////////
- Connection::Connection(boost::asio::io_service& io_service,
- boost::asio::ssl::context& context)
- : _strand(io_service),
- _socket(io_service, context)
- {
- }
- ssl_socket::lowest_layer_type& Connection::socket()
- {
- return _socket.lowest_layer();
- }
- boost::asio::io_service::strand& Connection::strand()
- {
- return _strand;
- }
- void Connection::start()
- {
- _socket.async_read_some(boost::asio::buffer(_buffer),
- _strand.wrap(
- boost::bind(
- &Connection::handleRead,
- shared_from_this(),
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred
- )
- )
- );
- }
- void Connection::handshake()
- {
- std::cout << "doing ssl handshake" << std::endl;
- _socket.async_handshake(boost::asio::ssl::stream_base::server,
- _strand.wrap(
- boost::bind(
- &Connection::handleHandshake,
- shared_from_this(),
- boost::asio::placeholders::error
- )
- )
- );
- }
- void Connection::handleHandshake(const boost::system::error_code& error)
- {
- if (!error)
- {
- _socket.async_read_some(boost::asio::buffer(_buffer),
- _strand.wrap(
- boost::bind(
- &Connection::handleRead,
- shared_from_this(),
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred
- )
- )
- );
- }
- else
- {
- std::cout << "error occured: " << error.message();
- this->close();
- }
- }
- void Connection::handleRead(const boost::system::error_code& e,
- std::size_t bytesTransferred)
- {
- if (!e) {
- // handle read data
- this->start();
- }
- else {
- this->close();
- }
- }
- void Connection::handleWrite(const boost::system::error_code& e)
- {
- if (!e) {
- this->start();
- }
- else {
- this->close();
- }
- }
- void Connection::sendResponse(const Response& response)
- {
- boost::asio::async_write(_socket,
- boost::asio::buffer(convertToString(response)),
- _strand.wrap(
- boost::bind(
- &Connection::handleWrite,
- shared_from_this(),
- boost::asio::placeholders::error
- )
- )
- );
- }
- void Connection::close()
- {
- boost::system::error_code ignoredCode;
- socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both,
- ignoredCode);
- }
- std::string Connection::getIPAddress()
- {
- return socket().remote_endpoint().address().to_string();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement