周末实在无聊啊
![](https://i-blog.csdnimg.cn/blog_migrate/7a540039b2d96332b70c2948cc906d31.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7a540039b2d96332b70c2948cc906d31.gif)
好吧,作为屌丝程序员,还是干点跟自己本行有关的东东
以前封装过scoket异步的程序。是基于linux下select写的,但是select效率比较低
所以最近想重新写下.
然后想写个跨平台的,正好试试自学的boost吧
boost是准C++标准库,非常强大的东西(是不是有点废话
),底层ASIO 套接字通讯在linux环境下使用epoll,windows下使用IOPC效率是没有问题的。
![](https://i-blog.csdnimg.cn/blog_migrate/a8621cfa41004f52bea16c5b6baf63c9.gif)
当然,网上有很多大神些的代码,我只是无聊练练手,跟大神门相差甚远。嘿嘿
好了,我懒人一个,直接贴代码算了
/*
* 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);
}
}
额 由于写完时间有点紧,所以没有编译,也没有测试
等有空我会测试下的