C/S框架 st_asio_wrapper 开发教程——宏(2019.10.17更新)

1.全局宏,服务端客户端均需要:

ST_ASIO_USE_STEADY_TIMER定时器采用boost::asio::steady_timer来实现。
ST_ASIO_USE_SYSTEM_TIMER定时器采用boost::asio::system_timer来实现,否则将采用boost::asio::deadline_timer来实现。

ST_ASIO_MAX_SEND_BUF

ST_ASIO_MAX_RECV_BUF

每个socket消息缓存最大字节数(接收和发送缓存共用,所以总的最大数为两倍),默认1M。注意这个缓存不会像ST_ASIO_MSG_BUFFER_SIZE一样预分配,而是用到多少分配多少。
ST_ASIO_ENHANCED_STABILITY增强的健壮性,如果开启这个宏,所有service对象都会在最外层(io_service::run)包一层try catch,以增加健壮性(当然,增加try  catch 是会有效率损失的),当捕捉到异常的时候,会回调on_exception虚函数,用户通过该函数的返回值来控制是否继续调用io_service::run。
ST_ASIO_PASSIVE_RECV 不主动接收消息,用户需要显示调用recv_msg来发起异步数据读取,如果你想在运行时替换解包器,必须定义该宏,且保证在调用recv_msg之前把解包器替换掉,否则会有race condition。
ST_ASIO_WANT_MSG_SEND_NOTIFY每次消息发送成功之后(成功送到本地SOCKET缓存),回调on_msg_send虚函数。
ST_ASIO_WANT_ALL_MSG_SEND_NOTIFY当发送缓存发空了之后,回调on_all_msg_send虚函数。
ST_ASIO_UNIFIED_OUT_BUF_NUM输出日志时用的缓存大小,注意是在栈上分配,注意栈溢出问题,如果你自定义了日志输出,该宏显然无意义。
ST_ASIO_NO_UNIFIED_OUT让st_asio_wrapper里面的所有输出失效。
ST_ASIO_CUSTOM_LOG自定义输出,此时你需要提供5个日志函数,函数名和签名参看unified_out类,且要么是静态的,要么是全局的。
ST_ASIO_FULL_STATISTIC详细的统计信息,包括时间消耗,如果不定义,所有时间消耗项都被不统计。统计的内容有请参看socket::statistic类的定义。
ST_ASIO_SERVICE_THREAD_NUMIO线程数量,用于运行io_service.run函数,所有回调函数(以on_开头的虚函数)都将会在这些线程中的某一个中被回调。
ST_ASIO_MAX_OBJECT_NUM对象池最多支持的对象数量,默认4096。
ST_ASIO_REUSE_OBJECT是否开启对象池,如果开启,当创建新对象时,将尝试使用已经被关闭的对象,此时将不会自动定时的释放被关闭的对象链表,请参看ST_ASIO_FREE_OBJECT_INTERVAL宏,默认不开启本宏。
ST_ASIO_FREE_OBJECT_INTERVAL说这个宏之前,要说一下object_pool的内部工作原理:当调用del_socket的时候(server_socket_base在on_recv_error里面的默认行为),object_pool的作法并不是删除这个对象,而是把这个对象移动到另外一个链表里面,这个链表里面的对象会被每ST_ASIO_FREE_OBJECT_INTERVAL秒遍历一次,以找到已经真正关闭了的对象(所谓真正关闭,就是已经被close了,而不仅仅是被shutdown了的对象,且没有任何未完成的异步调用),然后真正的从内存中释放它,原因是当del_socket的时候,可能还有其它的异步操作还没完成,或者完成了,但还在队列中没有被分发,如果此时从内存中释放对象,那么后面的异步回调的时候,可能会出现内存访问越界。如果未定义ST_ASIO_REUSE_OBJECT宏,ST_ASIO_FREE_OBJECT_INTERVAL宏会被自动定义(如果未显示定义的话)。单位为秒,默认10秒。
ST_ASIO_CLEAR_OBJECT_INTERVAL定时循环调用clear_obsoleted_object()以清除失效对象(移动到另外一个链表里面),如果在连接断开时你不方便调用del_socket,则对象池里面将会累积越来越多的失效对象(如果有连接出错,或者退出的话),你可以打开这个宏,让object_pool为你定时的做这些清除工作;注意,如果对象链表非常大,遍历链表是会影响效率的,如果你的连接是短连接,推荐开启这个功能(那你就不要再任何地方调用del_socket了),这样一次可清除多条连接,否则不推荐。单位为秒,该宏默认不开启。
ST_ASIO_DELAY_CLOSE关闭连接(shutdown)多少秒钟之后,可以安全释放对象或者重用对象(取决于ST_ASIO_REUSE_OBJECT是否被定义,定义了就是重用,否则释放)。如果定义为0,则st_asio_wrapper库将始终保证在没有任何异步调用之后才释放或者重用对象(会对效率造成一点点影响)。
ST_ASIO_GRACEFUL_SHUTDOWN_MAX_DURATION优雅关闭时,最长等待时间,单位为秒,默认5。
ST_ASIO_INPUT_QUEUE指定输入队列(send_msg用到的队列),目前有带锁和不带锁(线程不安全,所以需要你的业务保证线程的安全性)两种队列。
ST_ASIO_INPUT_CONTAINER指定输入队列所使用的容器,比如list、deque等,也可以是你自己的容器,只要提供必要的接口。
ST_ASIO_OUTPUT_QUEUE指定输出队列,目前有带锁和不带锁(线程不安全,所以需要你的业务保证线程的安全性)两种队列。
ST_ASIO_OUTPUT_CONTAINER指定输出队列所使用的容器,比如list、deque等,也可以是你自己的容器,只要提供必要的接口。
ST_ASIO_RECV_BUFFER_TYPE接收缓存的类型,比如它可以是boost::asio::mutable_buffers_1,或者std::vector<boost::asio::mutable_buffers_1>等,可以为所有asio支持的缓存类型。对于具体使用场合我举个例子,比如你正在使用ring buffer,那么一次你可能会提供两块非连续的缓存,那这个宏就能派上用场了。
ST_ASIO_HEARTBEAT_INTERVAL检测心跳包的频率,单位为秒,检测之前先检测连接有效性,如果心跳包超时,将断开连接(UDP不会)并回调on_heartbeat_error()函数,否则将发送一个心跳包。注意:如果从现在开始往前推ST_ASIO_HEARTBEAT_INTERVAL,在这个范围之内有消息被发送(接收的不算),则不会发送心跳包。
ST_ASIO_HEARTBEAT_MAX_ABSENCE如果判断心跳包超时,单位为次数,如果心跳包检测频度为5秒,这个值为3,则15秒后认为心跳包超时。
ST_ASIO_REUSE_SSL_STREAM让ssl支持重用和重连。如果ST_ASIO_REUSE_OBJECT被定义,而ST_ASIO_REUSE_SSL_STREAM没有,则编译任何ssl对象时,将报错。
ST_ASIO_AVOID_AUTO_STOP_SERVICE用asio::io_service::work (asio::executor_work_guard)包装io_service以绝对的防止service自动退出(除非是stop_service或者end_service)。
ST_ASIO_DECREASE_THREAD_AT_RUNTIME支持运行时增减service线程。
ST_ASIO_EXPOSE_SEND_INTERFACE暴露send_msg接口。


2.tcp客户端专用宏:

ST_ASIO_SERVER_IP服务器IP地址,用字符串形式表示,默认"127.0.0.1"
ST_ASIO_SERVER_PORT服务器端口,默认5050。
ST_ASIO_RECONNECT_INTERVAL当连接服务器失败时,延时多长时间重连,负数表示不重连,单位是毫秒,默认500毫秒。


3.tcp服务端专用宏:

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


4.udp客户端专用宏:

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


5.打包解包器专用宏(不属于st_asio_wrapper库):

ST_ASIO_MSG_BUFFER_SIZE用于解包的缓存大小,默认4000。它应该大于等于最长的消息包(打包后),拿默认的packer来说,它最大仅支持3998消息长度,因为还有一个2字节的包头。对于默认打包解包器,这个值的范围只能是1至65536,因为包头只用了两个字节来表达长度,如果想要超过这个限制,可定义HUGE_MSG宏。这个缓存越大,那么一次可接收的消息越多(如果SOCKET的缓存里面有数据的话),但不是越大越好,因为每一个解包器里面都有一个大小固定为MSG_BUFFER_SIZE的缓存(不管你用到了多少),而每一个tcp::socket_base都会有一个解包器(udp::socket_base类似),所以这个值越大,占用的内存也就越大。当然,如果你自定义了打包解包器,那上面等于没说,怎么控制内存分配由你说了算。
ST_ASIO_DEFAULT_PACKER自定义打包器,它是一个类名,必须提供默认构造函数(即没有参数的构造函数)。
ST_ASIO_DEFAULT_UNPACKER自定义解包器,它是一个类名,必须提供默认构造函数(即没有参数的构造函数)。
ST_ASIO_HUGE_MSG开启大消息支持,默认关闭。注意,大消息会占用更多内存,请看asio_client这个demo,里面有演示用法(注释状态),以及对于占用更多内存的解释。
ST_ASIO_HEAD_TYPE消息头数据类型,不可设置,如果定义了ST_ASIO_HUGE_MSG,则为uint32_t,否则为uint16_t。
ST_ASIO_HEAD_N2H网络序转主机序,不可设置,如果定义了ST_ASIO_HUGE_MSG,则为ntohl,否则为ntohs。
ST_ASIO_HEAD_N2H主机序转网络序,不可设置,如果定义了ST_ASIO_HUGE_MSG,则为htonl,否则为htons。
ST_ASIO_SCATTERED_RECV_BUFFER在接收数据时是否支持scattered缓存(parse_msg之前用的缓存),如果你正在使用ring buffer,你可能会一次提供两块不连续的缓存,此时这个宏就有用了。


以上宏都可以按工程为单位来修改,你只需要在include相应st_asio_wrapper相关头文件之前定义这些宏即可(但推荐定义在工程属性里面,以完全杜绝不同的cpp文件拿到不同的宏定义的情况),具体例子demo里面都有。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
st_asio_wrapper是一组类库,功能是对boost.asio的包装(调试环境:boost-1.51.0),目的是简化boost.asio开发; 其特点是效率高、跨平台、完全异步(当然这是从boost.asio继承而来)、自动重连,数据透明传输,自动解决分包粘包问题(你可以像udp一样使用它); 注:只支持tcp协议; 教程:http://blog.csdn.net/yang79tao/article/details/7724514 2.3版更新内容: 消息(std::string包装)不再用boost::shared_ptr包装,之前有过度使用智能指针之嫌。效率上,std::string如果支持引用记数,或者编译器支持std::move语义,是没有损失的(因为也不存在内存的拷贝,反而省了智能指针使用上的开销),幸好vc支持std::move语义(虽然它不支持引用记数,linux则都支持)。这样带来一个问题,原来所有的接口中的boost::shared_ptr<std::string>数据类型,全部换成了std::string引用,升级到2.3的朋友要注意修改之前重写虚函数的签名,如果不改,则重写肯定不生效,变成了新增加虚函数了(因为签名不一样)。这样向大家道歉,接口签名以后应该不会变化了,但可能增加接口; 修复使用std::advance的一个BUG,此BUG在linux下不存在,这里顺便向大家说一下,std::advance在vc和gcc下面,语义一样,但处理方式有些不同,一定要注意; 增加了个专门用于服务端压力测试的客户端框架st_test_client,并写了一个demo test_client,可以在performance_test目录下面找到; 把连接服务端逻辑从st_client剥离出来,定义了一个新的类st_connector,st_client和st_test_client将从它继承; 增加对vc2010的支持,和编译时对编译器版本的检测,如果达不到vc2010及其以上的版本,st_asio_wrapper将直接报错。
st_asio_wrapper是一组类,功能是对boost.asio的包装(调试环境:boost-1.51.0),目的是简化boost.asio开发; 其特点是效率高、跨平台、完全异步,当然这是从boost.asio继承而来; 自动重连,数据透明传输,自动解决分包粘包问题(你可以像udp一样使用它); 注:只支持tcp协议; 教程:http://blog.csdn.net/yang79tao/article/details/7724514 1.1版更新内容: 增加了自定义数据模式的支持,可用于st_asio_wrapper server与其它客户端的通信、或者st_asio_wrapper client与其它服务端的通信;当然,两端都是st_asio_wrapper的话,就用透明传输即可(1.0版已经支持了)。 1.2版更新内容: 修复BUG:当stop_service之后,再start_service时,client_base内部某些成员变量可能没有得到复位; 服务端增加修改监听地址功能,当然仍然要在start_service之前调用set_server_addr函数。 1.3版更新内容: 增加自定义消息格式的发送,这个本来是在1.1版本实现的,结果我漏掉了,只实现了自定义消息格式的接收。 1.4版更新内容: 将打包与解包器从client_base分离出来,以简化这个日益复杂的基类; 可以在运行时修改打包解包器。 1.5版更新内容: 增加ipv6支持,默认是ipv4,服务端和客户端都通过设置一个ipv6的地址来开启这个功能; 增加了一些服务端helper函数,小改了一下客户端set_server_addr函数签名(调换了两个参数的位置以保持和服务端一样)。 1.6版更新内容: 增加了接收消息缓存(改动较大,on_msg的语义有所变化,请看开发教程第三篇)。 1.7版更新内容: 修复vc2010下编译错误; 修复默认解包器BUG(同时修改解包器接口); 修复log输出BUG; 更好的包装了服务端类库,现在服务端可以像客户端一样简单的使用了(完全不用继承或者重写虚函数,申请一个对象即可); 结构大调整,类名大调整,请参看开发教程第一篇。 1.8版更新内容: 增加健壮性和稳定性; 退出服务更新优雅。 1.9版更新内容: 提高代码通用性; 可以指定服务端同时投递多少个async_accept; 修复BUG,此BUG可能造成数据发送不完全。 2.0版更新内容: 服务端增加对象池功能; 优化美化代码; 更规范化接口签名。 2.1版更新内容: 修复BUG,此BUG会造成st_client在stop_service之后,仍然可能尝试重新连接服务器; 在消息发送的时候,增加了一个参数can_overflow,用于确定是否在缓存满的时候返回失败,这在某些不能阻塞等待直到缓存可用的场合非常有用,比如on_msg; 当消息接收缓存满的时候,st_socket现在可以保证消息不丢失,之前的行为是调用on_recv_buffer_oveflow之后,丢弃消息; 更规范化接口签名; 更多更新请看st_asio_wrapper_socket.h,所有更新都会罗列在这个头文件的开头处,另外st_asio_wrapper_server.h的开头部分注释也很重要,有工作原理相关的说明。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值