一:什么是st_asio_wrapper
它是一个c/s网络编程框架,基于对boost.asio的包装(最低在boost-1.49.0上调试过),目的是快速的构建一个c/s系统;

二:st_asio_wrapper的特点
效率高、跨平台、完全异步,当然这是从boost.asio继承而来;
自动重连,数据透明传输,自动解决分包粘包问题(必须使用默认的打包解包器,这一特性表现得与udp一样);
只支持tcp和udp协议;

三:st_asio_wrapper的大体结构
st_asio_wrapper.h:
编译器版本测试,更新日志等;

st_asio_wrapper_base.h:
存放一些全局类、函数、宏以及日志输出等;

st_asio_wrapper_timer.h(class st_timer):
定时器类,以下类均需要,除了打包解包器;

st_asio_wrapper_socket.h(class st_socket):
st_tcp_socket和st_udp_socket的基类,主要负责消息派发相关功能;

st_asio_wrapper_tcp_socket.h(class st_tcp_socket):
tcp套接字类,用于tcp数据的收发,从st_socket继承;

st_asio_wrapper_udp_socket.h(class st_udp_socket):
udp套接字类,用于udp数据的收发,从st_socket继承;

st_asio_wrapper_packer.h(interface i_packer, class packer):
i_packer是打包器的接口,packer是st_asio_wrapper自带的打包器;

st_asio_wrapper_unpacker.h(interface i_unpacker, class unpacker):
i_unpacker是解包器的接口,unpacker是st_asio_wrapper自带的解包器;

st_asio_wrapper_service_pump.h(interface i_service, class st_service_pump):
asio的io_servie包装类,用于运行st_asio_wrapper的所有service对象(st_server_base, st_sclient, st_tcp_client_base, st_udp_client_base);

st_asio_wrapper_object_pool.h(class st_object_pool):
对象池,从原来的st_server_base抽象出来,供st_server_base和st_client继承,于是乎,服务端和客户端(支持多条连接的)都有了对象池功能;

st_asio_wrapper_server.h(class st_server_base):
st_server是服务端的服务对象类,用于服务端的监听、接受客户端请求等,需要实现i_server接口;

st_asio_wrapper_server_socket.h(interface i_server, class st_server_socket):
前者用于从st_server获取必要的信息,和调用必要的接口;后者从st_tcp_socket继承,用于服务端的数据收发;

st_asio_wrapper_connector.h(class st_connector):
从st_tcp_socket继承,实现连接服务器(包括重连)逻辑;

st_asio_wrapper_client.h(class st_sclient_base, class st_client_base):
client相关的公共逻辑,比如遍历等,被st_tcp_client_base和st_udp_client_base继承;

st_asio_wrapper_tcp_client.h(class st_tcp_sclient, class st_tcp_client_base):
前者从st_connector继承,只支持一条连接,后者支持任意多条连接,他们实现了一些逻辑,以便被st_service_pump调用;

st_asio_wrapper_udp_client.h(class st_udp_sclient, class st_udp_client_base):
基于udp套接字的service对象;

st_asio_wrapper_ssl.h(class st_ssl_connector_base, class st_ssl_object_pool, class st_ssl_server_socket_base, class st_ssl_server_base):
所有st_asio_wrapper库支持的ssl相关的类库;

源代码及例程下载地址:
命令行:svn checkout http://st-asio-wrapper.googlecode.com/svn/trunk/ st-asio-wrapper-read-only
如果从svn客户端界面上打开,则只输入http://st-asio-wrapper.googlecode.com/svn/trunk/到地址栏即可
git:https://github.com/youngwolf-project/st_asio_wrapper/,另外,我的资源里面也有下载,但不是最新的。
QQ交流群:198941541
其中include文件夹里面是st_asio_wrapper的所有类、asio_client和asio_server配合用于演示最简单的数据收发、file_server和file_client用于演示文件传送、test_client和asio_server配合用于性能测试、udp_client演示udp通信,他们都基于st_asio_wrapper,可以看成是sample;

类库(包括demo)在vc下有几个警告,均可安全忽略;
        类库里面大量使用了c++0x特性,主要有:range-based for loop、lambda表达式、nullptr、auto、右值引用、泛型begin()和end()等;因此至少需要vc2010及其以上版本的编译器,或者gcc4.6以上;
        在vc2010和gcc4.6之前的编译器版本中,请使用兼容版本,在compatiable_edition文件夹里面(注意兼容版本的效率并不比普通版本低,甚至略高);
        推荐在能用的情况下,还是用普通版本(或者说标准版本,这是相对于兼容版本而言的),虽然效率没有提高,但你用在一个复杂的工程中时,可能普通版本效率会高,因为相同的代码下,c++0x的效率要普遍的高一些,在st_asio_wrapper里面没有表现出来,是因为我特别的对兼容版本做过优化(而且我的使用也有限,比如有些无法优化的地方,我刚好不需要使用,就躲过去了);
        需要开发者自己编译boost库,大概需要boost.system和boost.thread两个库。

五:开发教程(客户端)
客户端直接#include st_asio_wrapper_client.h,就可实现一个简单的客户端了,如下:

  1. //configuration
  2. #define SERVER_PORT     9527
  3. #define FORCE_TO_USE_MSG_RECV_BUFFER //force to use the msg recv buffer
  4. //configuration
  5. #include "st_asio_wrapper_client.h"
  6. using namespace st_asio_wrapper;
  7. #define QUIT_COMMAND    "quit"
  8. #define RESTART_COMMAND "restart"
  9. #define RECONNECT_COMMAND "reconnect"
  10. #define SUSPEND_COMMAND "suspend"
  11. #define RESUME_COMMAND  "resume"
  12. int main() {
  13. std::string str;
  14. st_service_pump service_pump;
  15. st_sclient client(service_pump);
  16. //there is no corresponding echo client demo as server endpoint
  17. //because echo server with echo client made dead loop, and occupy almost all the network resource
  18. client.set_server_addr(SERVER_PORT + 100, SERVER_IP);
  19. //  client.set_server_addr(SERVER_PORT, "::1"); //ipv6
  20. //  client.set_server_addr(SERVER_PORT, "127.0.0.1"); //ipv4
  21. service_pump.start_service(1);
  22. while(service_pump.is_running())
  23. {
  24. std::cin >> str;
  25. if (str == QUIT_COMMAND)
  26. service_pump.stop_service();
  27. else if (str == RESTART_COMMAND)
  28. {
  29. service_pump.stop_service();
  30. service_pump.start_service(1);
  31. }
  32. else if (str == RECONNECT_COMMAND)
  33. client.graceful_close(true);
  34. //the following two commands demonstrate how to suspend msg sending, no matter recv buffer been used or not
  35. else if (str == SUSPEND_COMMAND)
  36. client.suspend_send_msg(true);
  37. else if (str == RESUME_COMMAND)
  38. client.suspend_send_msg(false);
  39. else
  40. client.safe_send_msg(str);
  41. }
  42. }
  43. //restore configuration
  44. #undef SERVER_PORT
  45. #undef FORCE_TO_USE_MSG_RECV_BUFFER //force to use the msg recv buffer
  46. //restore configuration

以上例子中,客户端从控制台接收数据,调用safe_send_msg发送数据;当收到数据时,会输出到控制台(st_tcp_socket或者st_udp_socket实现);

其中,start_service开启服务,stop_service结束服务(退出时必须明确调用),is_running判断服务的运行状态;如果想修改服务端地址,则在调用start_service之前调用set_server_addr函数;
        stop_service之后,可再次调用start_service开启服务;
        不stop_service而直接想重连接,则以true调用st_connector的force_close或者graceful_close;
        当然,一般来说,客户端不会只把收到的数据显示到控制台这么简单,此时需要从st_tcp_sclient或者st_udp_sclient派生一个类(如果你有多条连接,则从st_connector或者st_udp_socket派生一个类,并用st_tcp_client或者st_udp_client来管理它,这个请参考test_client这个demo,它支持多条连接),然后有两种方法供你选择,一:重写on_msg并在里面直接返回true(或者定义FORCE_TO_USE_MSG_RECV_BUFFER宏,至于为什么要这样,你需要看完所有st_asio_wrapper的一系列教程共四篇),然后再重写on_msg_handle并在里面做消息处理;二:重写on_msg,并在里面做消息处理,然后返回false。这两种方式的区别是:前者不会阻塞消息的接收,后者会,比如你的消息处理需要1秒,那么在这1秒钟之内,前者与接收消息并行,后者则不能接受消息,直到消息处理结束。另一个区别是:前者需要接收缓存,后者不需要。当然,这里说的阻塞,是指对当前套接字的阻塞,与其它套接字无关,比如在服务端,有两个套接字,当你处理套接字1的消息时,无论你用前面的哪一种方法,都不可能阻塞套接字2的消息接收。关于这个话题,请参看教程第四篇
        在消息发送成功之后,你有一次机会得到通知,那就是重写on_msg_send函数,它的参数就是这个消息(注意,是打包后的);
        每调用一次send_msg或者safe_send_msg,对方必定收到一次一模一样的数据,二次开发者不用再考虑分包粘包问题(必须使用默认的打包解包器),这一特点你完全可以把它当成udp的行为;
        st_socket里面有发送消息缓存,所以当二次开发者有数据需要发送的时候,可以随时调用send_msg(注意缓存满的问题,safe_send_msg保证数据发送成功,当缓存满时会等待)而不用关心当前连接是否已经建立,它会在条件适当的时候,为你发送数据。

你可能需要修改的宏有以下几类:
1.全局宏,服务端客户端均需要:
        UNIFIED_OUT_BUF_NUM:unified_out类使用的缓存空间大小,默认2048;
        MAX_MSG_LEN:消息最大长度(打包后的,拿默认的packer来说,它最大仅支持3998消息长度,因为还有一个2字节的包头),默认4000。对于默认打包器解包器,这个长度范围只能是1至(65535-2),因为包头只用了两个字节的缘故,如果想要超过这个限制,可定义HUGE_MSG宏;
        HUGE_MSG:开户大消息支持,默认关闭。注意,大消息会占用大内存,请看asio_client这个demo,里面有演示用法(注释状态),以及对于占用大内在的解释;
        MAX_MSG_NUM:每个st_socket消息缓存最大消息条数(接收和发送缓存共用,所以总的最大消息条数是2倍的MAX_MSG_NUM),默认1024;
        ENHANCED_STABILITY:增强的健壮性,如果开启这个宏,所有service对象都会在最外层(io_service.run)包一层try catch,以增加健壮性,当然,增加try是会有效率损失的,本宏默认不开启;
        FORCE_TO_USE_MSG_RECV_BUFFER:始终使用消息接收缓存,这个是编译期优化,前面说了,on_msg()返回true代表使用消息接收缓存,如果你的on_msg()永远返回true,则可以开启这个宏,那么st_tcp_socket或者st_udp_socket将不再调用on_msg()(根本不存在这个虚函数了)而是直接将消息放入消息接收缓存,这样可以提高一些效率,默认不开启本宏;
        NO_UNIFIED_OUT:让st_asio_wrapper里面的所有输出失效;
        CUSTOM_LOG:自定义输出,此时你需要提供5个日志函数,函数名和签名参看unified_out类,且要么是静态的,要么是全局的。
        DEFAULT_PACKER:自定义打包器,它是一个类名,必须提供默认构造函数(即没有参数的构造函数)。
        DEFAULT_UNPACKER:自定义解包器,它是一个类名,必须提供默认构造函数(即没有参数的构造函数)。
        ST_SERVICE_THREAD_NUM:IO线程数量,用于运行io_service.run函数。
        MAX_OBJECT_NUM:对象池最多支持的对象数量,默认4096;
        REUSE_OBJECT:是否开启对象池,如果开启,当创建新对象时,将尝试使用已经被关闭的对象,此时将不会自动定时的释放被关闭的对象链表,请参看SOCKET_FREE_INTERVAL宏,默认不开启本宏;
        SOCKET_FREE_INTERVAL:说这个宏之前,要说一下st_object_pool的内部工作原理:当调用del_object的时候(st_server_socket在on_recv_error里面的默认行为),st_object_pool的作法并不是删除这个对象,而是把这个对象移动到另外一个链表里面,这个链表里面的对象会被每SOCKET_FREE_INTERVAL秒遍历一次,以找到已经关闭超过CLOSED_SOCKET_MAX_DURATION秒钟的对象,然后真正的从内存中释放它,原因是当del_object的时候,可能还有其它的异步操作还没完成,或者完成了,但还在队列中没有被分发,如果此时从内存中释放对象,那么后面的异步回调的时候,可能会出现内存访问越界。这个问题可以通过为每一个异步调用都绑定一个指向本对象this指针的shared_ptr做为参数,但过度使用shared_ptr会影响到效率。单位为秒,默认10秒。如果开启了REUSE_OBJECT,则本宏根本不使用(也就不存在定时遍历了),因为被关闭的对象已经放入对象池,等着被重用,不能释放;
        AUTO_CLEAR_CLOSED_SOCKET:服务端是否定时的循环的调用clear_all_closed_object()以清除已经被关闭的套接字,如果你不方便调用del_object,则对象池里面将会累积越来越多的被关闭了的对象(如果有连接出错,或者退出的话),你可以打开这个宏,让st_object_pool为你定时的做这些清除工作;注意,如果对象链表非常大,遍历链表是会影响效率的;遍历的时间间隔由CLEAR_CLOSED_SOCKET_INTERVAL定义,默认不开启本宏;
        CLEAR_CLOSED_SOCKET_INTERVAL:定时调用clear_all_closed_object()间隔,单位为秒,默认60秒,如果未开启AUTO_CLEAR_CLOSED_SOCKET,则本宏根本不使用(也就不存在定时调用clear_all_closed_object()了);
        CLOSED_SOCKET_MAX_DURATION:关闭连接多少秒钟之后,可以安全释放对象或者重用对象(取决于REUSE_OBJECT是否被定义,定义了就是重用,否则释放),默认为5秒。

2.tcp客户端专用宏:
        GRACEFUL_CLOSE_MAX_DURATION:优雅关闭时,最长等待时间,单位为秒,默认5。
        SERVER_IP:服务器IP地址,用字符串形式表示,默认"127.0.0.1";
        SERVER_PORT:服务器端口,默认5050;
        RE_CONNECT_INTERVAL:当连接服务器失败时,延时多长时间重连,单位是毫秒,默认500毫秒;
        RE_CONNECT_CONTROL:打开此宏之后,可以控制重连接次数,运行时也可修改。

3.tcp服务端专用宏:
        SERVER_PORT:服务器端口(服务器IP如果要设置的话,只能调用set_server_addr接口,不能通过宏来实现),默认5050;
        TCP_DEFAULT_IP_VERSION:在不指定服务端IP时,通过这个宏指定IP协议的版本(v4还是v6,取值分别是boost::asio::ip::tcp::v4()和boost::asio::ip::tcp::v6()),如果指定了IP,则版本从ip地址中分析得来;
        ASYNC_ACCEPT_NUM:最多同时投递多少个异步accept调用,默认1;
        NOT_REUSE_ADDRESS:关闭端口重用,udp也用使用此宏。

4.udp客户端专用宏:
        UDP_DEFAULT_IP_VERSION:在不指定IP时,通过这个宏指定IP协议的版本(v4还是v6,取值分别是boost::asio::ip::udp::v4()和boost::asio::ip::udp::v6()),如果指定了IP,则版本从ip地址中分析得来;

以上宏都可以按工程为单位来修改,你只需要在include相应st_asio_wrapper相关头文件之前,定义这些宏即可,具体例子demo里面都有。

from:http://blog.csdn.net/yang79tao/article/details/7724514

boost.asio包装类st_asio_wrapper开发教程(2014.5.23更新)(一)-----转的更多相关文章

  1. boost.asio包装类st_asio_wrapper开发教程(一)

    一:什么是st_asio_wrapper它是一个c/s网络编程框架,基于对boost.asio的包装(最低在boost-1.49.0上调试过),目的是快速的构建一个c/s系统: 二:st_asio_w ...

  2. boost.asio包装类st_asio_wrapper开发教程(转)

    一:什么是st_asio_wrapper它是一个c/s网络编程框架,基于对boost.asio的包装(最低在boost-1.49.0上调试过),目的是快速的构建一个c/s系统: 二:st_asio_w ...

  3. boost.asio包装类st_asio_wrapper开发教程(2013.12.8更新)(二)

    如果你是偶然浏览到这里,请先看 源代码及例程下载地址:命令行:svn checkout http://st-asio-wrapper.googlecode.com/svn/trunk/ st-asio ...

  4. MyEclipse WebSphere开发教程:安装和更新WebSphere 6.1, JAX-WS, EJB 3.0(二)

    你开学,我放价!MyEclipse线上狂欢继续!火热开启中>> [MyEclipse最新版下载] MyEclipse支持Java EE技术(如JAX-WS和EJB 3.0),它们以功能包的 ...

  5. MyEclipse WebSphere开发教程:安装和更新WebSphere 6.1, JAX-WS, EJB 3.0(四)

    MyEclipse超值折扣 限量 100 套! 立即开抢>> [MyEclipse最新版下载] MyEclipse支持Java EE技术(如JAX-WS和EJB 3.0),它们以功能包的形 ...

  6. MyEclipse WebSphere开发教程:安装和更新WebSphere 6.1, JAX-WS, EJB 3.0(三)

    MyEclipse超值折扣 限量 100 套! 立即开抢>> [MyEclipse最新版下载] MyEclipse支持Java EE技术(如JAX-WS和EJB 3.0),它们以功能包的形 ...

  7. MyEclipse WebSphere开发教程:安装和更新WebSphere 6.1, JAX-WS, EJB 3.0(一)

    你开学,我放价!MyEclipse线上狂欢继续!火热开启中>> [MyEclipse最新版下载] MyEclipse支持Java EE技术(如JAX-WS和EJB 3.0),它们以功能包的 ...

  8. MyEclipse WebSphere开发教程:安装和更新WebSphere 6.1, JAX-WS, EJB 3.0(七)

    [周年庆]MyEclipse个人授权 折扣低至冰点!立即开抢>> [MyEclipse最新版下载] MyEclipse支持Java EE技术(如JAX-WS和EJB 3.0),它们以功能包 ...

  9. MyEclipse WebSphere开发教程:安装和更新WebSphere 6.1, JAX-WS, EJB 3.0(六)

    [周年庆]MyEclipse个人授权 折扣低至冰点!立即开抢>> [MyEclipse最新版下载] MyEclipse支持Java EE技术(如JAX-WS和EJB 3.0),它们以功能包 ...

随机推荐

  1. Qt 操作 pdf 文件

    写了好久的东西,不小心按了下返回键就没了.CSDN居然没自动保存,坑爹啊 原本还有很多信息的,现在直入正题吧. QT没有内置PDF操作的功能(其实有一个,QPrinter,不过只能写不能读,基本是半残 ...

  2. Flask web开发 处理POST请求(登录案例)

    本文我们以一个登录例子来说明Flask对 post请求的处理机制. 1.创建应用目录,如 mkdir   example cd example 2.在应用目录下创建  run.py文件,内容如下 fr ...

  3. php 解析url 和parse_url使用

    通过url进行传值,是php中一个传值的重要手段.所以我们要经常对url里面所带的参数进行解析,如果我们知道了url传递参数名称,例如 /index.php?name=tank&sex=1#t ...

  4. leetcode第一刷_Maximal Rectangle

    这个题比刚才那个更难. 假设没做过上一个,这个简直是无情. 先想一个笨笨的解法,如何确定一个矩形呢?找一个左上角,然后每行的看能延伸到什么位置.注意随着行数的添加,列数是仅仅能变短,不能变长. 想一下 ...

  5. linux路由表配置

    一.原理说明 1.路由表(table)从0到255进行编号,每个编号可以对应一个别名,编号和别名的对应关系在linux下放在/etc/iproute2/rt_tables这个文件里,一般0编号的tab ...

  6. ListView优化问题

    可以参考:http://blog.csdn.net/bill_ming/article/details/8817172和http://blog.csdn.net/xiangjai/article/de ...

  7. stm32中断优先级

    VIC_IRQChannelPreemptionPriority:先占优先级  NVIC_IRQChannelSubPriority:从优先级 高先占优先级中断可以打断低先占优先级的中断,即可中断嵌套 ...

  8. JVM调优总结(一)-- 一些概念

    数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对象本身, ...

  9. How to calculate the undo_retention time

    UNDO_RETENTION The undo_retention is a initialization parameter of the undo tablespace. The initiali ...

  10. XSS学习笔记(四)-漏洞利用全过程

    <script type="text/javascript" reload="1">setTimeout("window.location ...