听起来基于继承的解决方案可能更适合您。
这是一个示例基类,boost::signals2
用于发出接收到的消息的信号:
class Connection
{
public:
typedef boost::signals2::signal<void (const std::vector<char>&)>
PacketReceived;
protected:
PacketReceived packet_received_;
size_t max_rx_packet_size_;
std::vector<char> read_buffer_;
std::deque<std::vector<char> > tx_queue_;
void read_handler(boost::system::error_code const& error,
size_t bytes_transferred)
{
if (boost::asio::error::operation_aborted != error)
{
if (error)
; // TODO handle the error, it may be a disconnect.
else
{
read_buffer_.resize(bytes_transferred);
packet_received_(read_buffer_);
enable_reception(max_rx_packet_size_);
}
}
}
void write_handler(boost::system::error_code const& error,
size_t bytes_transferred)
{
if (boost::asio::error::operation_aborted != error)
{
tx_queue_.pop_front();
if (error)
; // TODO handle the error, it may be a disconnect.
else
if (!tx_queue_.empty())
transmit();
}
}
virtual void receive() = 0;
virtual void transmit() = 0;
explicit Connection() :
packet_received_(),
max_rx_packet_size_(),
read_buffer_(),
tx_queue_()
{}
public:
virtual void close() = 0;
virtual ~Connection()
{}
void connectPacketReceived(const PacketReceived::slot_type& slot)
{ packet_received_.connect(slot); }
void enable_reception(size_t max_rx_packet_size)
{
max_rx_packet_size_ = max_rx_packet_size;
receive();
}
const std::vector<char>& read_buffer() const
{ return read_buffer_; }
#if defined(BOOST_ASIO_HAS_MOVE)
void send(std::vector<char>&& packet )
#else
void send(const std::vector<char>& packet )
#endif
{
bool queue_empty(tx_queue_.empty());
tx_queue_.push_back(packet);
if (queue_empty)
transmit();
}
};
下面是实现 SSL 套接字的类的概要:
class SslConnection :
public Connection,
public boost::enable_shared_from_this<SslConnection>
{
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket_;
virtual void receive()
{
ssl_socket_.async_read_some(boost::asio::buffer(read_buffer_),
boost::bind(&SslConnection::read_handler, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
virtual void transmit()
{
boost::asio::async_write(ssl_socket_,
boost::asio::buffer(tx_queue_.front()),
boost::bind(&SslConnection::write_handler, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
SslConnection(boost::asio::io_service& io_service,
boost::asio::ssl::context& ssl_context) :
Connection(),
ssl_socket_(io_service, ssl_context)
{}
public:
static boost::shared_ptr<SslConnection> create
(boost::asio::io_service& io_service,
boost::asio::ssl::context& ssl_context)
{
return boost::shared_ptr<SslConnection>
(new SslConnection(io_service, ssl_context));
}
virtual void close()
{
boost::system::error_code ignoredEc;
ssl_socket_.lowest_layer().close(ignoredEc);
}
};