Realistic 3D camera system
3D camera system components
connection.hpp
Go to the documentation of this file.
1 //
2 // connection.hpp
3 // ~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef SERIALIZATION_CONNECTION_HPP
12 #define SERIALIZATION_CONNECTION_HPP
13 
14 #include <asio.hpp>
15 #include <boost/archive/text_iarchive.hpp>
16 #include <boost/archive/text_oarchive.hpp>
17 #include <boost/bind.hpp>
18 #include <boost/shared_ptr.hpp>
19 #include <boost/tuple/tuple.hpp>
20 #include <iomanip>
21 #include <string>
22 #include <sstream>
23 #include <vector>
24 
25 namespace s11n_example {
26 
28 
35 {
36 public:
39  : socket_(io_service)
40  {
41  }
42 
46  {
47  return socket_;
48  }
49 
51  template <typename T, typename Handler>
52  void async_write(const T& t, Handler handler)
53  {
54  // Serialize the data first so we know how large it is.
55  std::ostringstream archive_stream;
56  boost::archive::text_oarchive archive(archive_stream);
57  archive << t;
58  outbound_data_ = archive_stream.str();
59 
60  // Format the header.
61  std::ostringstream header_stream;
62  header_stream << std::setw(header_length)
63  << std::hex << outbound_data_.size();
64  if (!header_stream || header_stream.str().size() != header_length)
65  {
66  // Something went wrong, inform the caller.
68  socket_.get_io_service().post(boost::bind(handler, error));
69  return;
70  }
71  outbound_header_ = header_stream.str();
72 
73  // Write the serialized data to the socket. We use "gather-write" to send
74  // both the header and the data in a single write operation.
75  std::vector<asio::const_buffer> buffers;
76  buffers.push_back(asio::buffer(outbound_header_));
77  buffers.push_back(asio::buffer(outbound_data_));
78  asio::async_write(socket_, buffers, handler);
79  }
80 
82  template <typename T, typename Handler>
83  void async_read(T& t, Handler handler)
84  {
85  // Issue a read operation to read exactly the number of bytes in a header.
86  void (connection::*f)(
87  const asio::error_code&,
88  T&, boost::tuple<Handler>)
89  = &connection::handle_read_header<T, Handler>;
90  asio::async_read(socket_, asio::buffer(inbound_header_),
91  boost::bind(f,
92  this, asio::placeholders::error, boost::ref(t),
93  boost::make_tuple(handler)));
94  }
95 
99  template <typename T, typename Handler>
101  T& t, boost::tuple<Handler> handler)
102  {
103  if (e)
104  {
105  boost::get<0>(handler)(e);
106  }
107  else
108  {
109  // Determine the length of the serialized data.
110  std::istringstream is(std::string(inbound_header_, header_length));
111  std::size_t inbound_data_size = 0;
112  if (!(is >> std::hex >> inbound_data_size))
113  {
114  // Header doesn't seem to be valid. Inform the caller.
116  boost::get<0>(handler)(error);
117  return;
118  }
119 
120  // Start an asynchronous call to receive the data.
121  inbound_data_.resize(inbound_data_size);
122  void (connection::*f)(
123  const asio::error_code&,
124  T&, boost::tuple<Handler>)
125  = &connection::handle_read_data<T, Handler>;
126  asio::async_read(socket_, asio::buffer(inbound_data_),
127  boost::bind(f, this,
128  asio::placeholders::error, boost::ref(t), handler));
129  }
130  }
131 
133  template <typename T, typename Handler>
135  T& t, boost::tuple<Handler> handler)
136  {
137  if (e)
138  {
139  boost::get<0>(handler)(e);
140  }
141  else
142  {
143  // Extract the data structure from the data just received.
144  try
145  {
146  std::string archive_data(&inbound_data_[0], inbound_data_.size());
147  std::istringstream archive_stream(archive_data);
148  boost::archive::text_iarchive archive(archive_stream);
149  archive >> t;
150  }
151  catch (std::exception& e)
152  {
153  // Unable to decode data.
155  boost::get<0>(handler)(error);
156  return;
157  }
158 
159  // Inform caller that data has been received ok.
160  boost::get<0>(handler)(e);
161  }
162  }
163 
164 private:
166  asio::ip::tcp::socket socket_;
167 
169  enum { header_length = 8 };
170 
172  std::string outbound_header_;
173 
175  std::string outbound_data_;
176 
178  char inbound_header_[header_length];
179 
181  std::vector<char> inbound_data_;
182 };
183 
184 typedef boost::shared_ptr<connection> connection_ptr;
185 
186 } // namespace s11n_example
187 
188 #endif // SERIALIZATION_CONNECTION_HPP
void async_read(T &t, Handler handler)
Asynchronously read a data structure from the socket.
Definition: connection.hpp:83
Provides core I/O functionality.
Definition: io_service.hpp:184
post(ASIO_MOVE_ARG(CompletionHandler) handler)
Request the io_service to invoke the given handler and return immediately.
pylon Camera Software Suite for Linux for Use with Basler Gigabit the pylon Viewer and the IP Configurator applications might not be available System I340 and I350 series Although the pylon software will work with any GigE network we would recommend to use one of these adapters USB For U3V devices a USB3 capable USB controller is necessary For best performance and stability we highly recommend a kernel the following settings should be i e
Provides stream-oriented socket functionality.
mutable_buffers_1 buffer(const mutable_buffer &b)
Create a new modifiable buffer from an existing buffer.
Definition: buffer.hpp:706
boost::shared_ptr< connection > connection_ptr
Definition: connection.hpp:184
void handle_read_data(const asio::error_code &e, T &t, boost::tuple< Handler > handler)
Handle a completed read of message data.
Definition: connection.hpp:134
connection(asio::io_service &io_service)
Constructor.
Definition: connection.hpp:38
Invalid argument.
Definition: error.hpp:113
void async_write(const T &t, Handler handler)
Asynchronously write a data structure to the socket.
Definition: connection.hpp:52
const MutableBufferSequence & buffers
Definition: read.hpp:521
int bind(socket_type s, const socket_addr_type *addr, std::size_t addrlen, asio::error_code &ec)
Definition: socket_ops.ipp:278
The connection class provides serialization primitives on top of a socket.
Definition: connection.hpp:34
Class to represent an error code value.
Definition: error_code.hpp:80
asio::io_service & get_io_service()
Get the io_service associated with the object.
asio::ip::tcp::socket & socket()
Definition: connection.hpp:45
void handle_read_header(const asio::error_code &e, T &t, boost::tuple< Handler > handler)
Definition: connection.hpp:100