经过一天的简单学习,尝试自己写一个简单的服务器,能够实现以下三大回调功能:onConnect onMessage onClose
下面直接贴出代码
1.BaseServer抽象类
BaseServer.h
/*
name:BaseServer
use:the basest server
author:hezijian([email protected])
*/
#ifdef _MSC_VER
#define _WIN32_WINNT 0x0501
#endif
#ifndef _BASE_SERVER_H_
#define _BASE_SERVER_H_
#include
#include "SERVER_CONSTANT.h"
using namespace boost::asio;
using boost::system::error_code;
using ip::tcp;
class Session{
public:
Session(io_service& iosev):
m_buf((char*)malloc(SERVER_CONTANT::SESSION_BUF_LEN)),
m_socket(iosev)
{
memset(m_buf,0,SERVER_CONTANT::SESSION_BUF_LEN);
}
~Session(){
delete[] m_buf;
}
inline ip::tcp::socket& getSocket(){return m_socket;}
inline char* getBuf(){return m_buf;}
private:
ip::tcp::socket m_socket;
char* m_buf;
};
class BaseServer
{
public:
BaseServer(io_service &iosev);
//初始化
void init();
//等待连接
void start();
//当有连接时
void connect(std::shared_ptr pSession, error_code ec);
//当有消息传递时
void message(std::shared_ptr pSession, error_code ec);
//当断开连接时
void close(std::shared_ptr pSession, error_code ec);
//以下是回调函数,由子类重写
virtual void onConnect(std::shared_ptr pSession, error_code ec)=0;
virtual void onMessage(std::shared_ptr pSession, error_code ec)=0;
virtual void onClose(std::shared_ptr pSession, error_code ec)=0;
private:
io_service &m_iosev;
ip::tcp::acceptor m_acceptor;
int m_unique_id;
};
#endif
BaseServer.cpp
#include "BaseServer.h"
#include
BaseServer::BaseServer(io_service &iosev):
m_iosev(iosev),m_acceptor(iosev, tcp::endpoint(tcp::v4(), SERVER_CONTANT::PORT)),m_unique_id(1){
init();
}
void BaseServer::init(){
return;
}
void BaseServer::start(){
std::shared_ptr pSession(new Session(m_iosev));
m_acceptor.async_accept(pSession->getSocket(),
std::bind(&BaseServer::connect,this, pSession, std::placeholders::_1));
}
void BaseServer::connect(std::shared_ptr pSession, error_code ec){
std::cout <<
"一个新的连接:" << pSession->getSocket().remote_endpoint().address()
<< std::endl;
onConnect(pSession,ec);
if(ec) return;
//继续等待连接
start();
pSession->getSocket().async_read_some(buffer(pSession->getBuf(),SERVER_CONTANT::SESSION_BUF_LEN),
std::bind(&BaseServer::message,this,pSession,std::placeholders::_1));
}
void BaseServer::message(std::shared_ptr pSession, error_code ec){
if(ec){
BaseServer::close(pSession,ec);
return;
}
std::cout <<
"从客户端"<< pSession->getSocket().remote_endpoint().address() << "收到数据:" << pSession->getBuf()
<< std::endl;
onMessage(pSession,ec);
//清空缓冲区,继续等待数据
memset(pSession->getBuf(),0,sizeof(pSession->getBuf()));
pSession->getSocket().async_read_some(buffer(pSession->getBuf(),SERVER_CONTANT::SESSION_BUF_LEN),
std::bind(&BaseServer::message,this,pSession,std::placeholders::_1));
}
void BaseServer::close(std::shared_ptr pSession, error_code ec){
std::cout << boost::system::system_error(ec).what() << std::endl;
std::cout << pSession->getSocket().remote_endpoint().address() << " disconnect" << std::endl;
pSession->getSocket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, const_cast<:system::error_code>(ec));
pSession->getSocket().close(const_cast<:system::error_code>(ec));
onClose(pSession,ec);
return;
}
说明,BaseServer是一个抽象类,必须由子类重写回调函数才能实例化,SERVER_CONSTANT是服务器常量的管理头文件。
Session暂时是一个包装了socket和buf的类,以后可能还会丰富修改
2.MyServer继承BaseServer
MyServer.h
#ifndef _MY_SERVER_H_
#define _MY_SERVER_H_
#include "BaseServer.h"
class MyServer : public BaseServer{
public:
MyServer(io_service& iosev);
virtual void onConnect(std::shared_ptr pSession, error_code ec);
virtual void onMessage(std::shared_ptr pSession, error_code ec);
virtual void onClose(std::shared_ptr pSession, error_code ec);
};
#endif
MyServer.cpp
#include "MyServer.h"
MyServer::MyServer(io_service& iosev):BaseServer(iosev){
}
void MyServer::onConnect(std::shared_ptr pSession, error_code ec){
printf("onConnect\n");
}
void MyServer::onMessage(std::shared_ptr pSession, error_code ec){
printf("onMessage\n");
}
void MyServer::onClose(std::shared_ptr pSession, error_code ec){
printf("onClose\n");
}
3.main函数
#include "MyServer.h"
#include
int main(int argc, char* argv[])
{
try{
io_service iosev;
MyServer sev(iosev);
// 开始等待连接
sev.start();
std::cout << "服务器启动成功!" << std::endl;
iosev.run();
}catch(std::exception e){
std::cout << e.what() << std::endl;
}
return 0;
}
原文:http://blog.csdn.net/hezijian22/article/details/41621595