基于BOOST::ASIO封装的异步套接字

来源:互联网 发布:剑灵数据库 编辑:程序博客网 时间:2024/05/05 00:02
周末实在无聊啊
好吧,作为屌丝程序员,还是干点跟自己本行有关的东东

以前封装过scoket异步的程序。是基于linux下select写的,但是select效率比较低
所以最近想重新写下.
然后想写个跨平台的,正好试试自学的boost吧

boost是准C++标准库,非常强大的东西(是不是有点废话),底层ASIO 套接字通讯在linux环境下使用epoll,windows下使用IOPC效率是没有问题的。

当然,网上有很多大神些的代码,我只是无聊练练手,跟大神门相差甚远。嘿嘿

好了,我懒人一个,直接贴代码算了
/* * socket_session.h * *  Created on: 2014-11-1 *      Author: JingJing */#ifndef _SOCKET_SESSION_H_#define _SOCKET_SESSION_H_#include <string>#include <boost/asio.hpp>#include <boost/smart_ptr.hpp>#include <boost/bind.hpp>#include <boost/function.hpp>#include<boost/enable_shared_from_this.hpp>using namespace boost;using namespace boost::asio;using boost::system::error_code;using ip::tcp;#define max_len (1024 * 4)typedef boost::shared_array<char> SharedArrayPtr;typedef boost::function<void(const boost::system::error_code&,char*,const size_t)> OnRecvCallBack;typedef boost::function<void()> OnErrorCallBack;typedef boost::function<void(const boost::system::error_code&)> OnWriteCallBack;class CSocketSession;typedef boost::shared_ptr<CSocketSession>  SocketSessionPtr;class CSocketSession : public boost::enable_shared_from_this<CSocketSession>{public:    CSocketSession(io_service &ioSev);    ~CSocketSession(void);    void SendData(const SharedArrayPtr pData,size_t nDataSize);    ip::tcp::socket& GetSocket();    void StartRead(size_t recvSize = 0);    void RegisterHanleRead(OnRecvCallBack callback);    void UnRegisterHanleRead();    void RegisterOnError(OnErrorCallBack callback);    void UnRegisterOnError();    void RegisterHandleWrite(OnWriteCallBack callback);    void UnRegisterHandleWrite();protected:    void HandleReadSome(const boost::system::error_code& error, const size_t bytes_transferred);    void HandleRead(const boost::system::error_code& error, const size_t bytes_transferred, boost::shared_array<char> pSzRecvBuf);    void HandleWrite(const boost::system::error_code& error,const SharedArrayPtr pData);    ip::tcp::socket m_socket;    io_service &m_ioService;    OnRecvCallBack m_callBack;private:    char m_dataRecvBuff[max_len];    int m_errExit;    OnRecvCallBack m_recvCallBack;    OnErrorCallBack m_errorCallBack;    OnWriteCallBack m_writeCallBack;};#endif

/* * socket_session.cpp * *  Created on: 2014-11-1 *      Author: JingJing */#include "StdAfx.h"#include "SocketSession.h"#include "Log.h"CSocketSession::CSocketSession(io_service &ioSev)     :m_ioService(ioSev),    m_recvCallBack(NULL),    m_errorCallBack(NULL),    m_writeCallBack(NULL),    m_errExit(0),    m_socket(ioSev){}CSocketSession::~CSocketSession(void){    m_socket.close();}void CSocketSession::RegisterHanleRead(OnRecvCallBack callback){    LOG_TRACE("[CSocketSession]Register recv call back function!");    m_recvCallBack = callback;}void CSocketSession::UnRegisterHanleRead(){    LOG_TRACE("[CSocketSession]Unregister recv call back function!");    m_recvCallBack = NULL;}void CSocketSession::RegisterOnError(OnErrorCallBack callback){    LOG_TRACE("[CSocketSession]Register on error call back function!");    m_errorCallBack = callback;}void CSocketSession::UnRegisterOnError(){    LOG_TRACE("[CSocketSession]Unregister on error call back function!");    m_errorCallBack = NULL;}void CSocketSession::RegisterHandleWrite(OnWriteCallBack callback){    LOG_TRACE("[CSocketSession]Register handle write call back function!");    m_writeCallBack = callback;}void CSocketSession::UnRegisterHandleWrite(){    m_writeCallBack = NULL;}void CSocketSession::HandleReadSome(const error_code& error, const size_t bytes_transferred){    if (error)    {        m_errExit = 1;        if(m_errorCallBack != NULL)        {            m_errorCallBack();        }else        {            LOG_WARN("[CSocketSession]Not set on error call back function!");        }    }    if(NULL != m_recvCallBack)    {        m_recvCallBack(error,(char*)m_dataRecvBuff,bytes_transferred);    }else    {        LOG_WARN("[CSocketSession]Not set on recv call back function!");    }}void CSocketSession::HandleRead(const boost::system::error_code& error, const size_t bytes_transferred, boost::shared_array<char> pSzRecvBuf){    if (error)    {        m_errExit = 1;        if(m_errorCallBack != NULL)        {            m_errorCallBack();        }else        {            LOG_WARN("[CSocketSession]Not set on error call back function!");        }    }    if(NULL != m_recvCallBack)    {        m_recvCallBack(error, pSzRecvBuf.get(), bytes_transferred);    }else    {        LOG_WARN("[CSocketSession]Not set on recv call back function!");    }}void CSocketSession::HandleWrite(const error_code& error, const SharedArrayPtr pData){    if(m_writeCallBack != NULL)    {        m_writeCallBack(error);    }else    {        LOG_WARN("[CSocketSession]Not set handle write call back function!");    }}void CSocketSession::SendData(const SharedArrayPtr pData,size_t nDataSize){    boost::asio::async_write(m_socket,        boost::asio::buffer(pData.get(), nDataSize),        boost::bind(&CSocketSession::HandleWrite, shared_from_this(),        boost::asio::placeholders::error,pData));}void CSocketSession::StartRead(size_t recvSize){    if(m_errExit)    {        return;    }    memset(m_dataRecvBuff, 0, max_len);    if(recvSize == 0)    {        m_socket.async_read_some(boost::asio::buffer(m_dataRecvBuff, max_len),            boost::bind(&CSocketSession::HandleReadSome, shared_from_this(),            boost::asio::placeholders::error,            boost::asio::placeholders::bytes_transferred));    }else    {        try        {            boost::shared_array<char>  pSzRecvBuf = boost::shared_array<char>(new char[recvSize + 1]);            memset(pSzRecvBuf.get(), 0, recvSize + 1);            boost::asio::async_read(m_socket,boost::asio::buffer(pSzRecvBuf.get(), recvSize),                boost::bind(&CSocketSession::HandleRead, shared_from_this(),                boost::asio::placeholders::error,                boost::asio::placeholders::bytes_transferred, pSzRecvBuf));        }        catch (...)        {            LOG_WARN("[CSocketSession]StartRead faield!");        }        }}ip::tcp::socket& CSocketSession::GetSocket(){    return m_socket;}

/* * client_session.h * *  Created on: 2014-11-1 *      Author: JingJing */#ifndef _CLIENT_SESSION_H_#define _CLIENT_SESSION_H_#include "socketsession.h"typedef boost::function<void(SocketSessionPtr,const boost::system::error_code&)> OnConnectCallBack;class CClientSession : public boost::enable_shared_from_this<CClientSession>{public:    CClientSession(io_service &ioSev);    virtual ~CClientSession(void);    void Connect(const char* address,const USHORT port);    void SendData(SharedArrayPtr pData,size_t nDataSize);    void RegisterHandleRead(OnRecvCallBack callBack);    void UnRegisterHandleRead();        SocketSessionPtr GetSockertPtr();        void UnRegisterHandleConnect();    void RegisterHandleConnect(OnConnectCallBack callBack);    void StartRead();private:    void HandleConnect(SocketSessionPtr socketPtr, const boost::system::error_code& error);    SocketSessionPtr m_pSocketSession;    OnConnectCallBack m_onConnectCallBack;};#endif /* CLIENT_SESSION_H_ */

/* * client_session.cpp * *  Created on: 2014-11-1 *      Author: JingJing */#include "StdAfx.h"#include "ClientSession.h"#include "Log.h"#include <iostream>using boost::asio::ip::tcp;using boost::asio::ip::address;CClientSession::CClientSession(io_service &ioSev):m_onConnectCallBack(NULL){    m_pSocketSession = boost::make_shared<CSocketSession>(ioSev);}CClientSession::~CClientSession(void){}SocketSessionPtr CClientSession::GetSockertPtr(){    return m_pSocketSession;}void CClientSession::HandleConnect(SocketSessionPtr socketPtr, const error_code& error){    if(m_onConnectCallBack != NULL)    {        m_onConnectCallBack(m_pSocketSession,error);        //LOG_WARN();        return;    }    LOG_WARN("[CClientSession]Not set on connect call back function!");}void CClientSession::RegisterHandleConnect(OnConnectCallBack callBack){    LOG_TRACE("[CClientSession]Register on connect call back function!");    m_onConnectCallBack = callBack;}void CClientSession::UnRegisterHandleConnect(){    m_onConnectCallBack = NULL;}void CClientSession::RegisterHandleRead(OnRecvCallBack callBack){    LOG_TRACE("[CClientSession]Register on read data call back function!");    m_pSocketSession->RegisterHanleRead(callBack);}void CClientSession::UnRegisterHandleRead(){    LOG_TRACE("[CClientSession]UnRegister on read data call back function!");    m_pSocketSession->UnRegisterHanleRead();}void CClientSession::StartRead(){    m_pSocketSession->StartRead();}void CClientSession::Connect(const char* address,const USHORT port){    //LOG_TRACE("[CClientSession]Connect to address [" <<address << "] port["<< port << "]");    try    {        tcp::endpoint endpoint(address::from_string(address), port);        m_pSocketSession->GetSocket().async_connect(endpoint,boost::bind(&CClientSession::HandleConnect,shared_from_this(),m_pSocketSession,            boost::asio::placeholders::error));    }    catch (std::exception &e)    {        LOG_ERROR("[CClientSession] Connect error:" << e.what());    }    }void CClientSession::SendData(SharedArrayPtr pData,size_t nDataSize){    m_pSocketSession->SendData(pData,nDataSize);}

/* * server_session.h * *  Created on: 2014-11-1 *      Author: JingJing */#ifndef _SERVER_SESSION_H_#define _SERVER_SESSION_H_#include "socketsession.h"#include <boost/shared_ptr.hpp>#include <boost/bind.hpp>#include <boost/function.hpp>typedef boost::function<void (boost::shared_ptr<CSocketSession>, const std::string)> OnNewConnectCallBack;class CServerSession : public boost::enable_shared_from_this<CServerSession>{public:    CServerSession(io_service &ioSev);    virtual ~CServerSession(void);    void Accept(const unsigned short port);    void SendData(SocketSessionPtr pSocketSession, SharedArrayPtr pData,size_t nDataSize);    void RegisterOnNewConnect(OnNewConnectCallBack callBack);        void StartRead(SocketSessionPtr pSocketSession);private:    void StartAccept();    void HandleAccept(SocketSessionPtr pSocketSession, const boost::system::error_code& error);    boost::shared_ptr<tcp::acceptor> m_pAcceptor;    OnNewConnectCallBack m_onConnectCallBack;    io_service& m_ioService;};#endif /* SERVER_SESSION_H_ */

/* * server_session.cpp * *  Created on: 2014-11-1 *      Author: JingJing */#include "StdAfx.h"#include "ServerSession.h"#include "Log.h"CServerSession::CServerSession(io_service &ioSev) : m_onConnectCallBack(NULL),m_ioService(ioSev){}CServerSession::~CServerSession(void){}void CServerSession::HandleAccept(boost::shared_ptr<CSocketSession> pSocketSession, const error_code& error){    if(m_onConnectCallBack != NULL)    {        std::string dstaddr = pSocketSession->GetSocket().remote_endpoint().address().to_string();        m_onConnectCallBack(pSocketSession, dstaddr);    }else    {        LOG_WARN("[CServerSession]Not set on connect call back function!");    }    StartAccept();}void CServerSession::RegisterOnNewConnect(OnNewConnectCallBack callBack){    LOG_TRACE("[CServerSession]ServerSession register on new connect call back function!");    m_onConnectCallBack = callBack;}void CServerSession::StartRead(SocketSessionPtr pSocketSession){    pSocketSession->StartRead();}void CServerSession::Accept(const unsigned short port){    LOG_TRACE("[CServerSession]Accept start : port[" << port << "]");    m_pAcceptor = boost::make_shared<tcp::acceptor>(m_ioService,tcp::endpoint(ip::tcp::v4(),port));    StartAccept();}void CServerSession::StartAccept(){    boost::shared_ptr<CSocketSession> pSocketSession = boost::make_shared<CSocketSession>(m_ioService);    m_pAcceptor->async_accept(pSocketSession->GetSocket(),        boost::bind(&CServerSession::HandleAccept,shared_from_this(),pSocketSession,boost::asio::placeholders::error));}void CServerSession::SendData(boost::shared_ptr<CSocketSession> pSocketSession, SharedArrayPtr pData,size_t nDataSize){    if(pSocketSession)    {        pSocketSession->SendData(pData,nDataSize);    }}

额 由于写完时间有点紧,所以没有编译,也没有测试
等有空我会测试下的

0 0