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 
14 {
15  boost::asio::ip::tcp::socket socket;
16  constexpr static int HEADER_LENGTH = 8;
17 
18  std::string create_outbound_header(int header)
19  {
20  std::ostringstream header_stream;
21  header_stream << std::setw(HEADER_LENGTH)
22  << std::hex
23  << header;
24  if (!header_stream || header_stream.str().size() != HEADER_LENGTH)
25  throw std::runtime_error("bad header");
26  return header_stream.str();
27  }
28 public:
29  connection(boost::asio::ip::tcp::socket socket)
30  : socket(std::move(socket))
31  {
32  }
33 
35  {
36  close();
37  }
38 
39  void close()
40  {
41  boost::system::error_code ec;
42  socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
43  socket.close();
44  }
45 
46  boost::asio::ip::tcp::socket& get_socket()
47  {
48  return socket;
49  }
50 
51  template <typename T>
52  void async_write(const T& t, boost::asio::yield_context yield)
53  {
54  std::ostringstream archive_stream;
55  boost::archive::text_oarchive archive(archive_stream);
56  archive << t;
57  std::string outbound_data = archive_stream.str();
58  std::string outbound_header = create_outbound_header(outbound_data.size());
59  std::vector<boost::asio::const_buffer> buffers;
60  buffers.push_back(boost::asio::buffer(outbound_header));
61  buffers.push_back(boost::asio::buffer(outbound_data));
62  boost::asio::async_write(socket, buffers, yield);
63  }
64 
65  template <typename T>
66  void async_read(T& t, boost::asio::yield_context yield)
67  {
68  char inbound_header[HEADER_LENGTH];
69  boost::asio::async_read(socket, boost::asio::buffer(inbound_header, HEADER_LENGTH), yield);
70  std::istringstream is(std::string(inbound_header, HEADER_LENGTH));
71  int size = 0;
72  if (!(is >> std::hex >> size))
73  {
74  throw std::runtime_error("bad header");
75  }
76  std::vector<char> inbound_data(size);
77  boost::asio::async_read(socket, boost::asio::buffer(inbound_data), yield);
78  std::string archive_data(&inbound_data[0], inbound_data.size());
79  std::istringstream archive_stream(archive_data);
80  boost::archive::text_iarchive archive(archive_stream);
81  archive >> t;
82  }
83 };
84 
85 using connection_ptr = std::shared_ptr<connection>;
void async_read(T &t, boost::asio::yield_context yield)
Definition: connection.hpp:66
connection(boost::asio::ip::tcp::socket socket)
Definition: connection.hpp:29
boost::asio::ip::tcp::socket & get_socket()
Definition: connection.hpp:46
void close()
Definition: connection.hpp:39
void async_write(const T &t, boost::asio::yield_context yield)
Definition: connection.hpp:52
Definition: connection.hpp:13
std::shared_ptr< connection > connection_ptr
Definition: connection.hpp:85
~connection()
Definition: connection.hpp:34