diff options
Diffstat (limited to '3rdparty/asio/src/examples/cpp03/porthopper')
4 files changed, 0 insertions, 548 deletions
diff --git a/3rdparty/asio/src/examples/cpp03/porthopper/.gitignore b/3rdparty/asio/src/examples/cpp03/porthopper/.gitignore deleted file mode 100644 index 692ea7e7e65..00000000000 --- a/3rdparty/asio/src/examples/cpp03/porthopper/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -client -server -*.ilk -*.manifest -*.pdb -*.tds diff --git a/3rdparty/asio/src/examples/cpp03/porthopper/client.cpp b/3rdparty/asio/src/examples/cpp03/porthopper/client.cpp deleted file mode 100644 index 15d8e4803c1..00000000000 --- a/3rdparty/asio/src/examples/cpp03/porthopper/client.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// -// client.cpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2016 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 <asio.hpp> -#include <boost/lambda/lambda.hpp> -#include <boost/lambda/bind.hpp> -#include <boost/lambda/if.hpp> -#include <boost/shared_ptr.hpp> -#include <algorithm> -#include <cstdlib> -#include <exception> -#include <iostream> -#include <string> -#include "protocol.hpp" - -using namespace boost; -using asio::ip::tcp; -using asio::ip::udp; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 3) - { - std::cerr << "Usage: client <host> <port>\n"; - return 1; - } - using namespace std; // For atoi. - std::string host_name = argv[1]; - std::string port = argv[2]; - - asio::io_context io_context; - - // Determine the location of the server. - tcp::resolver resolver(io_context); - tcp::endpoint remote_endpoint = *resolver.resolve(host_name, port).begin(); - - // Establish the control connection to the server. - tcp::socket control_socket(io_context); - control_socket.connect(remote_endpoint); - - // Create a datagram socket to receive data from the server. - boost::shared_ptr<udp::socket> data_socket( - new udp::socket(io_context, udp::endpoint(udp::v4(), 0))); - - // Determine what port we will receive data on. - udp::endpoint data_endpoint = data_socket->local_endpoint(); - - // Ask the server to start sending us data. - control_request start = control_request::start(data_endpoint.port()); - asio::write(control_socket, start.to_buffers()); - - unsigned long last_frame_number = 0; - for (;;) - { - // Receive 50 messages on the current data socket. - for (int i = 0; i < 50; ++i) - { - // Receive a frame from the server. - frame f; - data_socket->receive(f.to_buffers(), 0); - if (f.number() > last_frame_number) - { - last_frame_number = f.number(); - std::cout << "\n" << f.payload(); - } - } - - // Time to switch to a new socket. To ensure seamless handover we will - // continue to receive packets using the old socket until data arrives on - // the new one. - std::cout << " Starting renegotiation"; - - // Create the new data socket. - boost::shared_ptr<udp::socket> new_data_socket( - new udp::socket(io_context, udp::endpoint(udp::v4(), 0))); - - // Determine the new port we will use to receive data. - udp::endpoint new_data_endpoint = new_data_socket->local_endpoint(); - - // Ask the server to switch over to the new port. - control_request change = control_request::change( - data_endpoint.port(), new_data_endpoint.port()); - asio::error_code control_result; - asio::async_write(control_socket, change.to_buffers(), - ( - lambda::var(control_result) = lambda::_1 - )); - - // Try to receive a frame from the server on the new data socket. If we - // successfully receive a frame on this new data socket we can consider - // the renegotation complete. In that case we will close the old data - // socket, which will cause any outstanding receive operation on it to be - // cancelled. - frame f1; - asio::error_code new_data_socket_result; - new_data_socket->async_receive(f1.to_buffers(), - ( - // Note: lambda::_1 is the first argument to the callback handler, - // which in this case is the error code for the operation. - lambda::var(new_data_socket_result) = lambda::_1, - lambda::if_(!lambda::_1) - [ - // We have successfully received a frame on the new data socket, - // so we can close the old data socket. This will cancel any - // outstanding receive operation on the old data socket. - lambda::var(data_socket) = boost::shared_ptr<udp::socket>() - ] - )); - - // This loop will continue until we have successfully completed the - // renegotiation (i.e. received a frame on the new data socket), or some - // unrecoverable error occurs. - bool done = false; - while (!done) - { - // Even though we're performing a renegotation, we want to continue - // receiving data as smoothly as possible. Therefore we will continue to - // try to receive a frame from the server on the old data socket. If we - // receive a frame on this socket we will interrupt the io_context, - // print the frame, and resume waiting for the other operations to - // complete. - frame f2; - done = true; // Let's be optimistic. - if (data_socket) // Might have been closed by new_data_socket's handler. - { - data_socket->async_receive(f2.to_buffers(), 0, - ( - lambda::if_(!lambda::_1) - [ - // We have successfully received a frame on the old data - // socket. Stop the io_context so that we can print it. - lambda::bind(&asio::io_context::stop, &io_context), - lambda::var(done) = false - ] - )); - } - - // Run the operations in parallel. This will block until all operations - // have finished, or until the io_context is interrupted. (No threads!) - io_context.restart(); - io_context.run(); - - // If the io_context.run() was interrupted then we have received a frame - // on the old data socket. We need to keep waiting for the renegotation - // operations to complete. - if (!done) - { - if (f2.number() > last_frame_number) - { - last_frame_number = f2.number(); - std::cout << "\n" << f2.payload(); - } - } - } - - // Since the loop has finished, we have either successfully completed - // the renegotation, or an error has occurred. First we'll check for - // errors. - if (control_result) - throw asio::system_error(control_result); - if (new_data_socket_result) - throw asio::system_error(new_data_socket_result); - - // If we get here it means we have successfully started receiving data on - // the new data socket. This new data socket will be used from now on - // (until the next time we renegotiate). - std::cout << " Renegotiation complete"; - data_socket = new_data_socket; - data_endpoint = new_data_endpoint; - if (f1.number() > last_frame_number) - { - last_frame_number = f1.number(); - std::cout << "\n" << f1.payload(); - } - } - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << std::endl; - } - - return 0; -} diff --git a/3rdparty/asio/src/examples/cpp03/porthopper/protocol.hpp b/3rdparty/asio/src/examples/cpp03/porthopper/protocol.hpp deleted file mode 100644 index c79bc6b49f4..00000000000 --- a/3rdparty/asio/src/examples/cpp03/porthopper/protocol.hpp +++ /dev/null @@ -1,156 +0,0 @@ -// -// protocol.hpp -// ~~~~~~~~~~~~ -// -// Copyright (c) 2003-2016 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) -// - -#ifndef PORTHOPPER_PROTOCOL_HPP -#define PORTHOPPER_PROTOCOL_HPP - -#include <boost/array.hpp> -#include <asio.hpp> -#include <cstring> -#include <iomanip> -#include <string> -#include <strstream> - -// This request is sent by the client to the server over a TCP connection. -// The client uses it to perform three functions: -// - To request that data start being sent to a given port. -// - To request that data is no longer sent to a given port. -// - To change the target port to another. -class control_request -{ -public: - // Construct an empty request. Used when receiving. - control_request() - { - } - - // Create a request to start sending data to a given port. - static const control_request start(unsigned short port) - { - return control_request(0, port); - } - - // Create a request to stop sending data to a given port. - static const control_request stop(unsigned short port) - { - return control_request(port, 0); - } - - // Create a request to change the port that data is sent to. - static const control_request change( - unsigned short old_port, unsigned short new_port) - { - return control_request(old_port, new_port); - } - - // Get the old port. Returns 0 for start requests. - unsigned short old_port() const - { - std::istrstream is(data_, encoded_port_size); - unsigned short port = 0; - is >> std::setw(encoded_port_size) >> std::hex >> port; - return port; - } - - // Get the new port. Returns 0 for stop requests. - unsigned short new_port() const - { - std::istrstream is(data_ + encoded_port_size, encoded_port_size); - unsigned short port = 0; - is >> std::setw(encoded_port_size) >> std::hex >> port; - return port; - } - - // Obtain buffers for reading from or writing to a socket. - boost::array<asio::mutable_buffer, 1> to_buffers() - { - boost::array<asio::mutable_buffer, 1> buffers - = { { asio::buffer(data_) } }; - return buffers; - } - -private: - // Construct with specified old and new ports. - control_request(unsigned short old_port_number, - unsigned short new_port_number) - { - std::ostrstream os(data_, control_request_size); - os << std::setw(encoded_port_size) << std::hex << old_port_number; - os << std::setw(encoded_port_size) << std::hex << new_port_number; - } - - // The length in bytes of a control_request and its components. - enum - { - encoded_port_size = 4, // 16-bit port in hex. - control_request_size = encoded_port_size * 2 - }; - - // The encoded request data. - char data_[control_request_size]; -}; - -// This frame is sent from the server to subscribed clients over UDP. -class frame -{ -public: - // The maximum allowable length of the payload. - enum { payload_size = 32 }; - - // Construct an empty frame. Used when receiving. - frame() - { - } - - // Construct a frame with specified frame number and payload. - frame(unsigned long frame_number, const std::string& payload_data) - { - std::ostrstream os(data_, frame_size); - os << std::setw(encoded_number_size) << std::hex << frame_number; - os << std::setw(payload_size) - << std::setfill(' ') << payload_data.substr(0, payload_size); - } - - // Get the frame number. - unsigned long number() const - { - std::istrstream is(data_, encoded_number_size); - unsigned long frame_number = 0; - is >> std::setw(encoded_number_size) >> std::hex >> frame_number; - return frame_number; - } - - // Get the payload data. - const std::string payload() const - { - return std::string(data_ + encoded_number_size, payload_size); - } - - // Obtain buffers for reading from or writing to a socket. - boost::array<asio::mutable_buffer, 1> to_buffers() - { - boost::array<asio::mutable_buffer, 1> buffers - = { { asio::buffer(data_) } }; - return buffers; - } - -private: - // The length in bytes of a frame and its components. - enum - { - encoded_number_size = 8, // Frame number in hex. - frame_size = encoded_number_size + payload_size - }; - - // The encoded frame data. - char data_[frame_size]; -}; - -#endif // PORTHOPPER_PROTOCOL_HPP diff --git a/3rdparty/asio/src/examples/cpp03/porthopper/server.cpp b/3rdparty/asio/src/examples/cpp03/porthopper/server.cpp deleted file mode 100644 index b98a7d4b24d..00000000000 --- a/3rdparty/asio/src/examples/cpp03/porthopper/server.cpp +++ /dev/null @@ -1,189 +0,0 @@ -// -// server.cpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2016 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 <asio.hpp> -#include <boost/bind.hpp> -#include <boost/shared_ptr.hpp> -#include <cmath> -#include <cstdlib> -#include <exception> -#include <iostream> -#include <set> -#include "protocol.hpp" - -using asio::ip::tcp; -using asio::ip::udp; - -typedef boost::shared_ptr<tcp::socket> tcp_socket_ptr; -typedef boost::shared_ptr<asio::deadline_timer> timer_ptr; -typedef boost::shared_ptr<control_request> control_request_ptr; - -class server -{ -public: - // Construct the server to wait for incoming control connections. - server(asio::io_context& io_context, unsigned short port) - : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)), - timer_(io_context), - udp_socket_(io_context, udp::endpoint(udp::v4(), 0)), - next_frame_number_(1) - { - // Start waiting for a new control connection. - tcp_socket_ptr new_socket( - new tcp::socket(acceptor_.get_executor().context())); - acceptor_.async_accept(*new_socket, - boost::bind(&server::handle_accept, this, - asio::placeholders::error, new_socket)); - - // Start the timer used to generate outgoing frames. - timer_.expires_from_now(boost::posix_time::milliseconds(100)); - timer_.async_wait(boost::bind(&server::handle_timer, this)); - } - - // Handle a new control connection. - void handle_accept(const asio::error_code& ec, tcp_socket_ptr socket) - { - if (!ec) - { - // Start receiving control requests on the connection. - control_request_ptr request(new control_request); - asio::async_read(*socket, request->to_buffers(), - boost::bind(&server::handle_control_request, this, - asio::placeholders::error, socket, request)); - } - - // Start waiting for a new control connection. - tcp_socket_ptr new_socket( - new tcp::socket(acceptor_.get_executor().context())); - acceptor_.async_accept(*new_socket, - boost::bind(&server::handle_accept, this, - asio::placeholders::error, new_socket)); - } - - // Handle a new control request. - void handle_control_request(const asio::error_code& ec, - tcp_socket_ptr socket, control_request_ptr request) - { - if (!ec) - { - // Delay handling of the control request to simulate network latency. - timer_ptr delay_timer( - new asio::deadline_timer(acceptor_.get_executor().context())); - delay_timer->expires_from_now(boost::posix_time::seconds(2)); - delay_timer->async_wait( - boost::bind(&server::handle_control_request_timer, this, - socket, request, delay_timer)); - } - } - - void handle_control_request_timer(tcp_socket_ptr socket, - control_request_ptr request, timer_ptr /*delay_timer*/) - { - // Determine what address this client is connected from, since - // subscriptions must be stored on the server as a complete endpoint, not - // just a port. We use the non-throwing overload of remote_endpoint() since - // it may fail if the socket is no longer connected. - asio::error_code ec; - tcp::endpoint remote_endpoint = socket->remote_endpoint(ec); - if (!ec) - { - // Remove old port subscription, if any. - if (unsigned short old_port = request->old_port()) - { - udp::endpoint old_endpoint(remote_endpoint.address(), old_port); - subscribers_.erase(old_endpoint); - std::cout << "Removing subscription " << old_endpoint << std::endl; - } - - // Add new port subscription, if any. - if (unsigned short new_port = request->new_port()) - { - udp::endpoint new_endpoint(remote_endpoint.address(), new_port); - subscribers_.insert(new_endpoint); - std::cout << "Adding subscription " << new_endpoint << std::endl; - } - } - - // Wait for next control request on this connection. - asio::async_read(*socket, request->to_buffers(), - boost::bind(&server::handle_control_request, this, - asio::placeholders::error, socket, request)); - } - - // Every time the timer fires we will generate a new frame and send it to all - // subscribers. - void handle_timer() - { - // Generate payload. - double x = next_frame_number_ * 0.2; - double y = std::sin(x); - int char_index = static_cast<int>((y + 1.0) * (frame::payload_size / 2)); - std::string payload; - for (int i = 0; i < frame::payload_size; ++i) - payload += (i == char_index ? '*' : '.'); - - // Create the frame to be sent to all subscribers. - frame f(next_frame_number_++, payload); - - // Send frame to all subscribers. We can use synchronous calls here since - // UDP send operations typically do not block. - std::set<udp::endpoint>::iterator j; - for (j = subscribers_.begin(); j != subscribers_.end(); ++j) - { - asio::error_code ec; - udp_socket_.send_to(f.to_buffers(), *j, 0, ec); - } - - // Wait for next timeout. - timer_.expires_from_now(boost::posix_time::milliseconds(100)); - timer_.async_wait(boost::bind(&server::handle_timer, this)); - } - -private: - // The acceptor used to accept incoming control connections. - tcp::acceptor acceptor_; - - // The timer used for generating data. - asio::deadline_timer timer_; - - // The socket used to send data to subscribers. - udp::socket udp_socket_; - - // The next frame number. - unsigned long next_frame_number_; - - // The set of endpoints that are subscribed. - std::set<udp::endpoint> subscribers_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: server <port>\n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server s(io_context, atoi(argv[1])); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << std::endl; - } - - return 0; -} |