基于boost::asio封装搭建的简单服务器

经过一天的简单学习,尝试自己写一个简单的服务器,能够实现以下三大回调功能: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 <boost/asio.hpp>

#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<Session> pSession, error_code ec);

	//当有消息传递时
	void message(std::shared_ptr<Session> pSession, error_code ec);

	//当断开连接时
	void close(std::shared_ptr<Session> pSession, error_code ec);

	//以下是回调函数,由子类重写
	virtual void onConnect(std::shared_ptr<Session> pSession, error_code ec)=0;
	virtual void onMessage(std::shared_ptr<Session> pSession, error_code ec)=0;
	virtual void onClose(std::shared_ptr<Session> 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 <iostream>

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<Session> 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<Session> 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<Session> 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<Session> 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<boost::system::error_code&>(ec));
	pSession->getSocket().close(const_cast<boost::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<Session> pSession, error_code ec);

	virtual void onMessage(std::shared_ptr<Session> pSession, error_code ec);

	virtual void onClose(std::shared_ptr<Session> pSession, error_code ec);
};
#endif

MyServer.cpp

#include "MyServer.h"

MyServer::MyServer(io_service& iosev):BaseServer(iosev){

}
void MyServer::onConnect(std::shared_ptr<Session> pSession, error_code ec){

	printf("onConnect\n");
}

void MyServer::onMessage(std::shared_ptr<Session> pSession, error_code ec){

	printf("onMessage\n");
}

void MyServer::onClose(std::shared_ptr<Session> pSession, error_code ec){

	printf("onClose\n");
}

3.main函数

#include "MyServer.h"
#include <iostream>
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;
}
时间: 2024-10-12 11:22:58

基于boost::asio封装搭建的简单服务器的相关文章

改进基于Boost.Asio的聊天服务

Boost.Asio是个非常易用的C++异步网络库,官网上有很详细文档和示例代码.其中一个示例是聊天服务,分成chat_message.chat_client.chat_server这么三个部分.chat_server的启动代码如下. 1 if (argc < 2) 2 { 3 std::cerr << "Usage: chat_server <port> [<port> ...]\n"; 4 return 1; 5 } 6 7 boost::

C/C++利用Boost::Asio网络库建立自己的Socket服务器

引言 寸光阴,当下我们或许更需要利用现有的知识,应用现有的技术.网络是当前互联网的根本,了解网络便开始显得极其重要.今天我们利用Boost库中Asio部分,浅尝网络服务器.此处不做过于深入的开展,为达成学习目的,只做简单的异步并发服务器. 注意:本篇代码没有直接引用boost等命名空间,为的是新入门Boost的同学能够更好的了解每个参数在boost的具体命名空间位置,有助于更好的理解boost的布局. 版权所有:_OE_,转载请注明出处:http://blog.csdn.net/csnd_ayo

Boost.Asio的使用技巧

基本概念 Asio proactor I/O服务 work类 run() vs poll() stop() post() vs dispatch() buffer类 缓冲区管理 I/O对象 socket 信号处理 定时器 strand 参考 最近尝试使用了一下Boost.Asio,不知道是否因为各大公司都有自己相对成熟的网络库的缘故,网络上Asio相关的资料实在不多,而且很多翻来覆去就是那几个简单的示例,所以打算自己小结一下.总的来说Boost.Asio是个非常易用的库,避免了你在各种系统底层A

Boost Asio初探

一.简介 Boost Asio ( asynchronous input and output)关注数据的异步输入输出.Boost Asio 库提供了平台无关性的异步数据处理能力(当然它也支持同步数据处理).一般的数据传输过程需要通过函数的返回值来判断数据传输是否成功,而Boost Asio将数据传输分为两个独立的步骤: 采用异步任务的方式开始数据传输. 将传输结果通知调用端 与传统方式相比,它的优势在于程序在数据传输期间不会被阻塞. 二.I/O Services 与 I/O Objects 应

使用Boost.Asio编写通信程序

摘要:本文通过形像而活泼的语言简单地介绍了Boost::asio库的使用,作为asio的一个入门介绍是非常合适的,可以给人一种新鲜的感觉,同时也能让体验到asio的主要内容. Boost.Asio是一个跨平台的网络及底层IO的C++编程库,它使用现代C++手法实现了统一的异步调用模型. ASIO的同步方式 ASIO库能够使用TCP.UDP.ICMP.串口来发送/接收数据,下面先介绍TCP协议的读写操作.对于读写方式,ASIO支持同步和异步两种方式,首先登场的是同步方式,下面请同步方式自我介绍一下

C++——boost:asio的使用

背景知识 高效网络编程一般都要依赖于IO复用,IO复用是指同时发送并监听处理很多socket或者文件读写的事件.IO复用的高效方式目前常用的有两种:Reactor和Proactor.这两种方式在操作系统级都是异步和非阻塞的,也就是说用户提交了一个请求后都可以直接返回.但是Reactor在用户层级看来是同步的,就是在提交了一系列的操作给操作系统后,需要阻塞监听等待事件的发生,如果有事件发生则手动调用相关的函数进行处理,其具体在操作系统级利用的是操作系统的事件通知接口.而Proactor在用户看来是

boost asio 异步实现tcp通讯

---恢复内容开始--- asioboost 目录(?)[-] 一前言 二实现思路 通讯包数据结构 连接对象 连接管理器 服务器端的实现 对象串行化 一.前言 boost asio可算是一个简单易用,功能又强大可跨平台的C++通讯库,效率也表现的不错,linux环境是epoll实现的,而windows环境是iocp实现的.而tcp通讯是项目当中经常用到通讯方式之一,实现的方法有各式各样,因此总结一套适用于自己项目的方法是很有必要,很可能下一个项目直接套上去就可以用了. 二.实现思路 1.通讯包数

boost asio 学习(九) boost::asio 网络封装

http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=10 9. A boost::asio network wrapper (TCP) 现在我们了解asio和TCP网络方面的知识,我们可以尝试下封装网络底层.通过使用这个封装,我们可以重用代码并且将精力集中于业务逻 辑方面而不在网络通讯方面花费太多精力. 重要提示:本代码仅仅用于教学目的.不要在商业系统中使用该代码,

跨平台c++/boost/asio 简单的HTTP POST请求 客户端模型

作为一个呼应,写一个c++版本的同步http post客户端功能,如果你需要纯C版本,移步这里 linux下纯C简单的HTTP POST请求 客户端模型 讲解一下基本的的http post协议 通过\r\n,实现tcp的消息边界 每个请求的第一段 POST /a.b HTTP/1.1 POST http的方法,还有最常用的GET,当然还有其他的几种,略过 /a.b 请求的网页路径,比如如果是首页,最经常的就是/ HTTP/1.1 http协议的版本号,传说中已经出了2了,还有神奇的谷歌出的用来替