IAtari
Genetic algorithm generating AI capable to play Atari2600 games.
connection.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <boost/asio.hpp>
4 #include <boost/archive/text_iarchive.hpp>
5 #include <boost/archive/text_oarchive.hpp>
6 #include <functional>
7 #include <memory>
8 #include <iomanip>
9 #include <string>
10 #include <sstream>
11 #include <vector>
12 
25 class connection{
26  boost::asio::ip::tcp::socket socket;
27  constexpr static int HEADER_LENGTH = 8;
36  std::string create_outbound_header(int header){
37  std::ostringstream header_stream;
38  header_stream << std::setw(HEADER_LENGTH)
39  << std::hex
40  << header;
41  if (!header_stream || header_stream.str().size() != HEADER_LENGTH)
42  throw std::runtime_error("bad header");
43  return header_stream.str();
44  }
45 
46  public:
53  connection(boost::asio::ip::tcp::socket socket)
54  : socket(std::move(socket))
55  {
56  }
57 
64  close();
65  }
66 
72  void close(){
73  boost::system::error_code ec;
74  socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
75  socket.close();
76  }
77 
84  boost::asio::ip::tcp::socket& get_socket(){
85  return socket;
86  }
87 
88  template <typename T>
96  void async_write(const T& t, boost::asio::yield_context yield){
97  std::ostringstream archive_stream;
98  boost::archive::text_oarchive archive(archive_stream);
99  archive << t;
100  std::string outbound_data = archive_stream.str();
101  std::string outbound_header = create_outbound_header(outbound_data.size());
102  std::vector<boost::asio::const_buffer> buffers;
103  buffers.push_back(boost::asio::buffer(outbound_header));
104  buffers.push_back(boost::asio::buffer(outbound_data));
105  boost::asio::async_write(socket, buffers, yield);
106  }
107 
108  template <typename T>
116  void async_read(T& t, boost::asio::yield_context yield){
117  char inbound_header[HEADER_LENGTH];
118  boost::asio::async_read(socket, boost::asio::buffer(inbound_header, HEADER_LENGTH), yield);
119  std::istringstream is(std::string(inbound_header, HEADER_LENGTH));
120  int size = 0;
121  if (!(is >> std::hex >> size)){
122  throw std::runtime_error("bad header");
123  }
124  std::vector<char> inbound_data(size);
125  boost::asio::async_read(socket, boost::asio::buffer(inbound_data), yield);
126  std::string archive_data(&inbound_data[0], inbound_data.size());
127  std::istringstream archive_stream(archive_data);
128  boost::archive::text_iarchive archive(archive_stream);
129  archive >> t;
130  }
131 };
132 
133 using connection_ptr = std::shared_ptr<connection>;
connection(boost::asio::ip::tcp::socket socket)
Standard constructor. Initialize the connection by moving a socket.
Definition: connection.hpp:53
boost::asio::ip::tcp::socket & get_socket()
Return the associated socket.
Definition: connection.hpp:84
void async_write(const T &t, boost::asio::yield_context yield)
Write a value through the associated socket.
Definition: connection.hpp:96
std::string create_outbound_header(int header)
Transform an int into his hexadecimal value. May return an error if the inner outputStream is not pro...
Definition: connection.hpp:36
static constexpr int HEADER_LENGTH
Definition: connection.hpp:27
void async_read(T &t, boost::asio::yield_context yield)
Read a value through the associated socket. May return an error if the inner inputStream can't be rea...
Definition: connection.hpp:116
void close()
Disable then close the socket. May return an error if it fails to disable the socket.
Definition: connection.hpp:72
Handle networking.
Definition: connection.hpp:25
boost::asio::ip::tcp::socket socket
Definition: connection.hpp:26
std::shared_ptr< connection > connection_ptr
Definition: connection.hpp:133
~connection()
Standard destructor. Close the associated socket.
Definition: connection.hpp:63