Код будет в общей либе, поэтому хочется максимально проверить на возможные косяки.
#ifndef CONNECTION_H
#define CONNECTION_H
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <boost/asio.hpp>
namespace boost_ip = boost::asio::ip;
enum {
max_length = 1024
};
class connection {
public:
connection(boost::asio::io_service& io_service, short port)
: _endpoint()
, _socket(io_service, udp::endpoint(udp::v4(), port) ) {}
/** @brief Get boost UDP socket (both client and server side)
* @return socket (without any check) */
boost_ip::udp::socket& socket() {
return _socket;
}
/** @brief Read from socket to buffer */
void read() {
_socket.receive_from(
boost::asio::buffer(&_inbound_data[0], _inbound_data.size())
, _endpoint);
}
/** @brief Write buffer to socket */
template <typename InputIterator>
void write(InputIterator beg
, InputIterator end
, size_t packet_size) {
_socket.send_to(boost::asio::buffer(&_outgoing_data[0], packet_size)
, _endpoint);
}
/** @brief Async write buffer to socket
* This overloaded function does not flushes outgoing buffer,
* so buffer saved before will be sent
* @param handler custom completion handler for async operation
* @param packet_size transferring object size */
template <typename Handler>
void async_write(Handler handler, size_t packet_size) {
_socket.async_send_to(
boost::asio::buffer(&_outgoing_data[0], packet_size)
, _endpoint
, handler);
}
/** @brief Async write buffer to socket
* This overloaded function includes outgoing buffer flush and reassign.
* @param begin begin() iterator of serialized data container
* @param end end() iterator of serialized data container
* @param handler custom completion handler for async operation
* @param packet_size serialized object size */
template <typename Handler, typename InputIterator>
void async_write(InputIterator begin
, InputIterator end
, Handler handler
, size_t packet_size) {
set_outgoing_buffer(begin, end);
_socket.async_send_to(boost::asio::buffer(&_outgoing_data[0], packet_size)
, _endpoint
, handler);
}
/** @brief Async read buffer from socket
* @param handler custom completion handler for async operation */
template <typename Handler>
void async_read(Handler handler) {
_socket.async_receive_from(
boost::asio::buffer(&_inbound_data[0], _inbound_data.size())
, _endpoint
, handler);
}
/** @brief Get inbound buffer data for read-only access
* @return inbound buffer as c-array */
const char* get_inbound_buffer() const {
return _inbound_data.data();
}
/** @brief Get outgoing buffer data for read-only access
* @return outgoing buffer as c-array */
const char* get_outgoing_buffer() const {
return _outgoing_data.data();
}
/** @brief Set outgoing buffer before send
* @param beg begin() iterator of serialized data container
* @param end end() iterator of serialized data container */
template<typename InputIterator>
void set_outgoing_buffer(InputIterator beg, InputIterator end) {
std::memset(_outgoing_data.c_array(), 0x0, _outgoing_data.size());
std::copy(beg, end, _outgoing_data.begin());
}
/**@brief Set client-side endpoint
* @param e new endpoint */
void set_endpoint(const boost_ip::udp::endpoint& e){
_endpoint = e;
}
private:
/** @brief Endpoint (where should we send packet) */
boost_ip::udp::endpoint _endpoint;
/** @brief Boost UDP socket */
boost_ip::udp::socket _socket;
/** @brief Container to store inboiund data */
boost::array<char, max_length> _inbound_data;
/** @brief Container to store outgoing data */
boost::array<char, max_length> _outgoing_data;
};
#endif /* CONNECTION_H */