#ifndef _CONNECTION_H_
#define _CONNECTION_H_
#include "ByteBuffer.h"
#include <ctime>
#include <iostream>
#include <string>
#include <stdint.h>
#include <boost/bind.hpp>
#include <memory>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
class Connection: public boost::enable_shared_from_this<Connection>
{
public:
typedef std::shared_ptr<Connection> pointer;
explicit Connection(boost::asio::io_service& io_service);
virtual ~Connection();
boost::asio::ip::tcp::socket& socket();
virtual void OnConnected()=0;
virtual void Send(std::shared_ptr<uint8_t> buffer, int length);
bool Receive();
void Disconnect();
protected:
virtual void OnReceived(ByteBuffer &b) = 0;
private:
void handler(const boost::system::error_code& error, std::size_t bytes_transferred );
boost::asio::ip::tcp::socket socket_;
bool disconnecting;
};
#endif
#include "Connection.h"
using namespace std;
Connection::Connection(boost::asio::io_service& io_service)
: socket_(io_service),disconnecting(false)
{
}
Connection::~Connection()
{
//dtor
}
boost::asio::ip::tcp::socket& Connection::socket(){
return socket_;
}
void Connection::Send(std::shared_ptr<uint8_t> buf, int length){
boost::asio::async_write(socket_,boost::asio::buffer(buf.get(),length),
boost::bind(&Connection::handler, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
bool Connection::Receive(){
std::vector<uint8_t> buf(1000);
boost::asio::async_read(socket_,boost::asio::buffer(buf,1000),
boost::bind(&Connection::handler, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
int rcvlen=buf.size();
ByteBuffer b((std::shared_ptr<uint8_t>)buf.data(),rcvlen);
if(rcvlen <= 0){
buf.clear();
this->Disconnect();
return false;
}
OnReceived(b);
buf.clear();
return true;
}
void Connection::Disconnect()
{
if (!disconnecting) {
boost::system::error_code ec;
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_send,ec);
socket_.close(ec);
disconnecting = true;
}
}
void Connection::handler(const boost::system::error_code& error, std::size_t bytes_transferred ){
}