作者:yurunsun@gmail.com 新浪微博@孙雨润 新浪博客 CSDN博客日期:2012年11月28日
1. 背景介绍
1.1 什么是asio
2012年从5月份开始我主持了webyy服务器项目(http://www.yy.com/webyy.html),项目中没有按照惯例使用公司既有的基于epoll
的网络框架,而是尝试了C++ tr2标准中的实验网络库asio,无论从开发效率、程序性能、稳定性上来说,都是一次成功的尝试。虽然是商业项目,但使用了linux、asio、protobuf等大量开源项目,开发过程共也借鉴了其他一些开源项目,因此我决定把与公司无关的部分剥离一下,分享出来,尽到使用自由软件的义务。
asio由Christopher M. Kohlhoff大牛从2003年着手开发,2006年申请加入C++ tr1,2008年3月份加入boost1.35.0,按照boost与C++标准库的发展惯例,预测很快会加入C++标准库中。其中的async调用方式已经作为非常重要的新特性,加入到C++0x标准库。
1.2 asio的相关资料
asio官方提供了及其详细的文档、例子、教程,没有必要再累赘地将其转述一遍。如果有朋友对英文有些吃力,网上也早有很多翻译版。这里提供一些官方的文档资料:
-
非boost版本的asio —— http://think-async.com/
与boost::asio的主要区别就是名字空间是boost::asio还是asio。
-
boost::asio —— http://www.boost.org/doc/libs/1520/doc/html/boost_asio.html
-
申请加入tr2时的申报材料 —— 猛击此处下载高清pdf
-
proactor模式的首篇论文 —— 猛击此处下载高清pdf
-
使用asio的大型开源网络项目sip —— https://svn.resiprocate.org/rep/resiprocate/main
2. 源码参考
由于代码使用了一点其他的工具,所以并没有想让读者能够编译通过。但是对从头开始搭建服务器的朋友来说,一定是一份非常有价值的参考。
2.1 作为Client的模块
这部分供作为Client去连接其他服务器时使用。给出的源码中有三个类:TcpConnection, BizConnection, Client
. 其中
-
TcpConnection
提供了与协议无关的tcp连接,异步操作的结果以虚函数方式供派生类使用 -
BizConnection
继承自TcpConnection
,使用具体的协议解析报文 -
Client
使用BizConnection
,并提供了等待具体某条消息的wait_for、心跳、延迟等功能
2.1.1 tcpconnection.h
#ifndef TCPCONNECTION_H
#define TCPCONNECTION_H
/**
* @author yurunsun@gmail.com
*/
#include <asio.hpp>
#include <asio/deadline_timer.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/timer.hpp>
#include <sstream>
#include "safehandler.h"
class TcpConnection
: public boost::enable_shared_from_this<TcpConnection>
, private boost::noncopyable
{
public:
typedef std::vector<uint8_t> DataBuffer;
typedef boost::shared_ptr<TcpConnection> TcpPtr;
static TcpPtr create(asio::io_service& io_service, const string& name){return TcpPtr(new TcpConnection(io_service, name));}
virtual ~TcpConnection();
void start(const string& ip, const string& port);
void start(unsigned ip, uint16_t port);
void start(const string& ip, uint16_t port);
void stop();
bool isConnected() {return m_socket.is_open();}
/// Getters and Setters
void setName(const st