st_asio_wrapper使用FAQ(2017.7.24更新)

时间:2022-09-08 23:26:12
Q:tcp服务端(server_base)和tcp客户端(client_socket_base)都有个函数set_server_addr,有何区别?
A:典型的网络编程基本知识,服务端设置的是监听地址,客户端设置的是连接地址,这个问题并不是st_asio_wrapper特有的,属于网络编程基础知识。
Q:如何不让st_connector重连接?
A:重连接分两种情况,首次连接和断线之后的连接,st_asio_wrapper做一样的处理。当连接失败,或者连接断开之后,client_socket_base会回调prepare_reconnect虚函数,期望得到一个单位为毫秒的整数值,如果这个值大于等于0,则在sleep相应毫秒数之后,开始重连接,如果小于0,则不再重连接。
另外,如果你重写了on_recv_error,并且没有调用父类的同名函数,也没有调用socket::start函数的话,则也不会重新连接服务器(这种情况专指断线之后的重连)。
Q:什么是service,为什么有些时候service会自动退出?
A:从i_service继承得到的对象都是service对象,他们负责所有网络事件的调度,还有比如定时器之类。当service没有事可做的时候,就自动退出了(这是asio的设计),之前的st_asio_wrapper本来不会有service退出的情况,但最近由于添加了重连次数功能,所以客户端有可能会自动退出service(使用者放弃重连接)。那么如何防止客户端service自动退出呢,答案是定义ST_ASIO_AVOID_AUTO_STOP_SERVICE宏。
Q:为什么没有连接失败的事件?
A:在收到on_connect回调之前,都是连接失败的状态,不需要事件;如果已经成功的连接断开了,则会收到on_recv_error回调。
Q:接口被重写了,还需要调用父类的同名函数吗?
A:这个要看函数的具体功能,比如初始化之类的虚函数,重写之后,在最后一定要调用父类的同名函数,如果你不需要父类的逻辑(或者父类根本没有逻辑,比如on_msg_send),或者你的逻辑已经包括了父类的逻辑,则可以不调用父类的同名函数。
Q:如何不让st_asio_wrapper输出到控制台?
A:定义ST_ASIO_NO_UNIFIED_OUT,则st_asio_wrapper里面所有输出就失效了(demo里面的输出不会失败,因为是直接使用的crt函数,比如printf)。
Q:st_asio_wrapper的类继承层次是怎样的?
st_asio_wrapper使用FAQ(2017.7.24更新)

Q:st_asio_wrapper主要业务时序图?
st_asio_wrapper使用FAQ(2017.7.24更新)
客户端连接时序图
st_asio_wrapper使用FAQ(2017.7.24更新)
服务端接受连接时序图
st_asio_wrapper使用FAQ(2017.7.24更新)
消息接收并处理时序图,不使用消息缓存(客户端和服务端完全一样)
st_asio_wrapper使用FAQ(2017.7.24更新)
消息接收并处理时序图,使用消息缓存(客户端和服务端完全一样)
st_asio_wrapper使用FAQ(2017.7.24更新)
消息发送时序图(客户端和服务端完全一样)
Q:如何防止端口重用?
A:定义ST_ASIO_NOT_REUSE_ADDRESS宏。
Q:下载地址在哪里?
git: https://github.com/youngwolf-project/st_asio_wrapper/,ascs在与st_asio_wrapper同级目录里面,另外,我的资源里面也有下载,但不是最新的。
QQ交流群:198941541,这里面有每个版本的压缩包,全是最新的。
Q:在linux下如何编译demo?
release 版本是make;
debug版本是make debug。
Q:3.0版本更新了哪些内容?
1.service之间(比如multi_client_base和server_base之间)共享io_service和线程;
2.新增了一个io_service和线程包装类—service_pump,由它创建boost::io_service和执行serivce对象(比如multi_client_base);
3.增加了tcp::single_client_base和udp::single_service_base_sclient,用于只支持一条socket的情况,它们直接从client_socket_base和udp::sokcet_base继承,并且是一个service对象(都同时从i_service继承)。
Q:关于最近的boost_1.53版本。
建议大家能更新就更新,它解决一些bug,其中就有一个asio在windows下面死锁的bug,另外线程类解决了众多bug,还有当迭代器包装shared_ptr对象时,对迭代器调用->get()时,带来编译错误(正确的应该是相当于调用shared_ptr的.get()),这个bug也得到了解决;关键是,经过我详细的测试,发现st_asio_wrapper在53版本下面,带来了10%以上的效率提升(用demo test_client加上asio_server测试),而且让兼容版本的效率达到了甚至稍微超过了普通版本,可喜可贺!
Q:关于优化。
经过我在一台老的intel平台上用64bit ubuntu 12.10的测试,发现普通版本用O2优化,兼容版本用O优化,可以达到最高性能(实际的最佳优化可能还得根据使用场合自己测试)。
Q:关于boost 1.54的bug。
boost 1.54下的asio有非常严重的bug,请看这个连接: https://svn.boost.org/trac/boost/search?q=asio&noquickjump=1&ticket=on&milestone=on&changeset=on&wiki=on,所以我推荐大家暂时不要使用1.54版本,等1.55出来之后,直接升级到1.55。
Q:3.5版本更新了哪些内容?
A:一是代码重构,把原来的st_socket和st_udp_socket的公共逻辑抽象出来,放到了类st_socket里面,原来的st_socket改名为st_tcp_socket;把原来st_cleint和st_udp_client的公共逻辑抽象出来(包括st_sclient和st_sudp_client),放到了类st_client里面,原来的st_client改名为st_tcp_client、原来的st_sclient更名为st_tcp_scleint、原来的st_sudp_client更名为st_udp_scleint。二是增加了在运行时暂停消息发送和消息分发,具体怎么使用,有什么用,请参看教程 第五篇。三是将对象池逻辑从st_server_base抽象出来放入st_object_pool类里面供st_server_base和st_client继承,如此一来,客户端(支持多条连接的)也有对象池功能了,并且可以像服务端一样随时关闭套接字并del_object而不用担心野指针问题。
Q:2015.2.9号更新了哪些内容?
A:1. on_msg的返回值的意义进行了对调,现在返回true,相当于原来返回false,反之已然,这样做的目的是为了与on_msg_handle保持一致性,老代码如果想升级,需要小幅度修改一下代码,为此我很抱歉;
2. on_msg_handle的签名改为了bool on_msg_handle(msg_type& msg, bool link_down),返回true表示消息被处理,false表示延迟消息派发,具体有什么用,请参看教程 第五篇;如果连接断开,link_down将会被置为true,此时无论你返回true还是false,st_socket都将丢弃该消息而继续派发后面的消息,不再做延迟派发,因为连接断开的情况下,需要尽快的将剩余的消息派发完毕;
3. 增加了DISCARD_MSG_WHEN_LINK_DOWN宏,用于控制当连接断开时,是否继续派发剩余的消息,默认不开启。
Q:2015.2.9号到今天(2016.1.6日)更新了哪些内容?
A:解决一些demo中的bug;
让一些demo更易用,比如从运行参数获取服务器地址而不是写死在程序等;
自定义缓存支持;
解决udp连接被重置bug;
支持在编译阶段指定不同的打包解包器;
支持在运行时修改打包解包器;
对象池容器由set改为unordered_set;
增加了另外几个附送的打包解包器;
打包器与解包器可以生成不同的消息类;
解决了在SunOS(sparc)上的core dump(SIGBUG);
向下兼容至gcc 4.1;
完全由使用者控制重连接(是否重连接,等待多久时间重连接等);
支持异步优雅关闭;
兼容boost_1.60;
编译时增加-pthread选项,这是更标准的使用POSIX线程的方法;
Q:运行时替换打包解包器好用吗?
A:总体来说不好用,对于打包器,库本身没有做互斥,需要使用者在调用send_msg/post_msg/safe_send_msg和inner_packer的地方自行互斥,未做互斥一是因为效率,二是因为我觉得这个功能不常用,使用者完全可以把多种打包方式放在一个packer里面,然后通过一个type来决定使用哪一种打包方式,在需要替换打包器的地方,改为直接修改当前打包器的type变量即可;对于解包器,情况就更复杂了,只能在自己的reset,on_msg和构造函数里面替换自己的解包器,原因是,解包器返回了一个buffer给socket做异步调用,如果替换掉了解包器,如何保持这个buffer仍然有效?其实推荐的办法是,不同的协议通过不同的连接(socket)来发送,不同的socket是可以使用不同的打包解包器的,这一点完全不用质疑,另外也可以像上面推荐的打包器一样,通过内部一个type决定采用什么方式解包,需要替换解包器的地方,改为直接修改这个type变量。
Q:2016.3.27日累计更新
A:从一个打好的包里面获取原始数据,如果自定义打包器,可以选择不支持这个功能,不强求支持;
简化makefile,支持gmake,clang,类unix系统;
同步文档;
修改bug——从ssl::object_pool创建的对象,其id没有被更新,而是一个未初始化值,这也造成了ssl::server_base和ssl::multi_client_base无法支持多条连接;
如果定义了ST_ASIO_ENHANCED_STABILITY宏,则绝对保证对象被安全的释放或者重用,之前的实现是设置一个超时时间(比如5秒之后)然后释放或者重用,不是绝对安全的(因为有可能释放或者重用发生在异步调用结束之前,那当异步调用结束并回调对象的handler的时候,对象已经不存在了或者被重用了),现在哪怕将超时时间设置为0秒,也是绝对安全的了。注意这种安全的保证是有损效率的。


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