您的位置:首页 > 运维架构 > Linux

LinuxC/C++编程基础(20) 使用boost::asio搭建服务器简单实例

2012-12-09 13:16 1046 查看
一.crossdomain.h头文件的编写,如下:

#ifndef CROSSDOMAIN_H

#define CROSSDOMAIN_H

#include <string>

#include <boost/asio.hpp>

#include <boost/bind.hpp>

#include <boost/shared_ptr.hpp>

#include <boost/enable_shared_from_this.hpp>

using namespace boost;

class CrossDomain{

private:

struct Server;

shared_ptr<Server> m_pserver;//有的读者已经看出来了,这是基于pimpl的模式的一个实现

CrossDomain(asio::io_service& io_service,const std::string& local_port);

static CrossDomain* s_instance;

public:

static void create(asio::io_service& io_service,const std::string& local_port){//工厂模式以及单例模式

s_instance = new CrossDomain(io_service,local_port);

}

static CrossDomain* instance();

void startServer();

};

#endif

说明:(1)struct Server;只是一个前向声明

(2)startServer()函数在后面的实现中,会调用struct Server里面的start_server()函数,这便是pimpl模式的关键点

转载请注明出处:山水间博客,/article/2317653.html

二.crossdomain.cpp源文件中关键函数的实现,如下:

1.CrossDomain构造函数的实现,如下:

CrossDomain::CrossDomain(asio::io_service& io_service,const std::string& local_port)

:m_pserver(new Server(io_service,local_port)){

}

说明:可见在CrossDomain构造函数的实现中,把Server的一个实例对象交给了智能指针m_pserver管理

2.struct Server的构造函数的实现,如下:

Server(asio::io_service& io_service,const std::string& local_port)

:m_acceptor(io_service),m_listened(false),m_local_port(local_port)

{

//intend to leave it blank;

}

说明:该函数的关键点,及初始化了***m_acceptor,传递一个io_service对象给它

3.CrossDomain::startServer函数的实现,如下:

void CrossDomain::startServer(){

if(m_pserver != NULL){

m_pserver->start_server();

}

}

说明:由此可得,其实是调用了智能指针管理的Server对象的start_server()方法

转载请注明出处:山水间博客,/article/2317653.html

4.Server::start_server函数的实现,如下:

void start_server(){

std::cout<<"CrossDomain start_server..."<<std::endl;

if(!m_listened){

std::cout<<"try to listen"<<std::endl;

try{

tcp::endpoint ep(tcp::endpoint(tcp::v4(),atoi(m_local_port.c_str())));

m_acceptor.open(ep.protocol());//打开一个使用由ep指定的协议类型的***,protocol()函数自动返回与ep关联的协议类型

m_acceptor.bind(ep);//把***绑定到已经设置过的ep

m_acceptor.listen();//***开始监听

}catch(const system::error_code& ec){

std::cout<<"m_local_port: "<<m_local_port<<"already in use"<<std::endl;

return;

}catch(...){

std::cout<<"unknown error while trying to listen..."<<std::endl;

return;

}

m_listened = true;//表示监听成功

std::cout<<"listen port "<<m_local_port<<" successfully"<<std::endl;

}

/**

*说明:这里通过调用CrossDomainImpl的create函数创建一个CrossDomainImplPtr实例,因为下面异步async_accept()函数中要调用

*create函数需要的参数由m_acceptor的get_io_server()方法获得,实现很简单,这里略去

*/

//可以理解为每个new_server_impl代表了一个客户端的连接,由该new_server_impl对象处理与该客户端有关的数据收发

m_acceptor.async_accept(new_server_impl->getSocket()

,bind(&Server::handle_accept,this,new_server_impl,asio::placeholders::error));

std::cout<<"[Server::start_server()] end of Server::start_server() function..."<<std::endl;

}

5.CrossDomainImpl::create函数的实现,如下:

static CrossDomainImplPtr create(asio::io_service& io_service){

return CrossDomainImplPtr(new CrossDomainImpl(io_service));

}

说明:即调用了CrossDomainImpl的构造函数

6.CrossDomainImpl构造函数的实现,如下:

CrossDomainImpl(asio::io_service& io_service):m_socket(io_service){

}

说明:即完成了m_socket的相关初始化

7.Server::handle_accept函数的实现,如下:

void handle_accept(CrossDomainImpl::CrossDomainImplPtr pserver_impl,const system::error_code& err){

std::cout<<"CrossDomain handle_accept..."<<std::endl;

if(!err){

std::cout<<"CrossDomain everythine ok,start..."<<std::endl;

pserver_impl->start();//处理与客户端有关的数据收发

start_server();//接收另一个连接

}else{

pserver_impl->close();

}

}

8.CrossDomainImpl::start函数的实现,如下:

void start(){

std::cout<<"[CrossDomainImpl::start()]"<<std::endl;

start_read_some();

}

说明:即调用了CrossDomainImpl::start_read_some()读取从客户端发过来的数据

转载请注明出处:山水间博客,/article/2317653.html

9.CrossDomainImpl::start_read_some函数的实现,如下:

void start_read_some(){

std::cout<<"CrossDomainImpl::start_read_some()"<<std::endl;

m_socket.async_read_some(asio::buffer(m_readbuf,MaxReadSize)

,bind(&CrossDomainImpl::handle_read_some,shared_from_this()

,asio::placeholders::error()));

}

说明:是异步的读取

10.CrossDomainImpl::handle_read_some函数的实现,如下:

void handle_read_some(const system::error_code& err){

std::cout<<"CrossDomainImpl::handle_read_some()"<<std::endl;

if(!err){

std::string str(m_readbuf);

std::string reply("invalid");

if(str == "<policy-file-request/>"){

reply = "anything you wanna send back to client...";

}

asio::async_write(m_socket,asio::buffer("hello server"),bind(&CrossDomainImpl::handle_write

,shared_from_this(),asio::placeholders::error));

}

}

说明:异步读取完数据后,调用handle_write()函数发送数据到客户端

11.CrossDomainImpl::handle_write函数的实现,如下:

void handle_write(const system::error_code& error){

std::cout<<"CrossDomain handle_write,gonna close"<<std::endl;

close();

}

说明:这里只是示意调用了该方法

三.main.cpp的实现,如下:

#include "crossdomain.h"

int main(int argc,char** argv){

asio::io_service ios;

std::string local_port = "9999";

CrossDomain::create(ios,local_port);

if(CrossDomain::instance() != NULL){

CrossDomain::instance()->startServer();

}

ios.run();

return 0;

}

四.运行结果,如下:



说明:可见服务器已经运行起来了,正在等待客户端的连接...

参考文献:http://blog.csdn.net/sunyurun/article/details/8235304

转载请注明出处:山水间博客,/article/2317653.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: