1、请教boost:asio连接超时的问题
typedef boost::asio::ip::tcp::acceptor AcceptorType; typedef boost::asio::ip::tcp TcpType; AcceptorType m_acceptor; TcpType::endpoint endpoint(TcpType::v4(), m_port); m_acceptor.open(endpoint.protocol()); // 这里自会阻塞!!! m_...
2、如何使用boost.asio写一个简单的通信程序
boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介绍如何写一个简单的通信程序来告诉读者如何使用asio,希望对asio的初学者有所帮助。由于只是介绍其基本用法,作为例子的简单示例并不考虑很多的业务逻辑和异常处理,只是介绍基本用法,让初学者入门。
使用asio容易出错的一个主要原因是因为它是基于proactor模式实现的,asio有很多异步操作接口,这些异步接口稍不注意就会出现莫名奇妙的错误,所以要用好asio的第一步是理解其异步操思想。
异步操作思想
用户发起异步事件,asio将这些异步事件投递到一个队列中,用户发起的操作就返回了,io_service::run会处理异步事件队列中的所有的异步事件,它会将这些事件交给操作系统处理,操作系统处理完成之后会丢到asio的事件完成的队列中,io_service发现有完成队列中有完成事件了,就会通知用户处理完成事件。 所以用户要发起一个异步操作需要做三件事:
调用asio异步操作接口,发起异步操作;如:async_connect、async_read、async_write,这些异步接口需要一个回调函数入参,这个回调函数在事件完成时,由io_service触发。
调用io_service::run处理异步事件;发起一个异步操作,必须要保证io_service::run,因为io_service通过一个循环去处理这些异步操作事件的,如果没有事件就会退出,所以要保证异步事件发起之后,io_service::run还在运行。要保证一直run的一个简单办法就是使用io_service::work,它可以保证io_service一直run。
处理异步操作完成事件;在调用异步接口时会传入一个回调函数,这个回调函数就是处理操作完成事件的,比如读完成了,用户需要对这些数据进行业务逻辑的处理。
asio的的核心是io_service, 理解了asio异步接口的机制就容易找出使用asio过程中出现的问题了,在这里把一些常见的问题列出来,并分析原因和提出解决方法。
问题1:为什么我发起了异步操作,如连接或者写,对方都没有反应,好像没有收到连接请求或者没有收到数据? 答案:一个很可能的原因是io_service在异步操作发起之后没有run,解决办法是保持io_service的run。
问题2:为什么发送数据会报错? 答案:一个可能的原因是发送的数据失效了,异步发送要求发送的数据在回调完成之前都有效,异步操作只是将异步事件句柄投递到io_service队列中就返回了,并不是阻塞的,不注意这一点,如果是临时变量的数据,除了作用域就失效了,导致异步事件还没完成时数据就失效了。解决办法,保证发送数据在事件完成之前一直有效。
问题3:为什么监听socket时,会报“函数不正确”的异常? 答案:因为监听时,也要保证这个socket一直有效,如果是一个临时变量socket,在调用异步监听后超出作用域就失效了,解决办法,将监听的socket保存起来,使它的生命周期和acceptor一样长。
问题4:为什么连续调用异步操作时会报错? 答案:因为异步操作必须保证当前异步操作完成之后再发起下一次异步操作。解决办法:在异步完成事件处理完成之后再发起新的异步操作即可。
问题5:为什么对方半天收不到数据,过了半天才一下子收到之前发送的数据? 答案:因为socket是流数据,一次发送多少数据不是外界能控制的,这也是所谓的粘包问题。解决办法,可以在接收时指定至少收多少的条件,或者做tcp分包处理。
说了这么多,还是来看看例子吧,一个简单的通信程序:服务端监听某个端口,允许多个客户端连接上来,服务器将客户端发来的数据打印出来。 先看看服务端的需求,需求很简单,第一,要求能接收多个客户端;第二,要求把收到的数据打印出来。
要求能接收多个客户端是第一个要解决的问题,异步接收需要用到acceptor::async_accept,它接收一个socket和一个完成事件的回调函数。前面的问题3中提到监听的这个socket不能是临时变量,我们要把它保存起来,最好是统一管理起来。可以考虑用一个map去管理它们,每次一个新连接过来时,服务器自动分配一个连接号给这个连接,以方便管理。然而,socket是不允许拷贝的,所以不能直接将socket放入容器中,还需要外面包装一层才可以。
第二个问题是打印来自客户端的数据,既然要打印就需要异步读数据了。异步读是有socket完成,这个socket还要完成读写功能,为了简化用户操作,我将socket封装到一个读写事件处理器中,这个事件处理器只具备具备读和写的功能。服务器每次监听的时候我都会创建一个新的事件处理器并放到一个map中,客户端成功连接后就由这个事件处理器去处理各种读写事件了。 根据问题1,异步读写时要保证数据的有效性,这里我将一个固定大小的缓冲区作为读缓冲区。为了简单起见我使用同步发送,异步接收。
3、各位对用Boost里面的asio进行网络编程有什么看法
简介 Boost.Asio是一个跨平台的C++库,主要用于网络和其他一些底层的I/O编程。 在大版量的网络编程库中,Boost.Asio是其权中的佼佼者,它于2005年加入到Boost,已经被广泛的测试并且应用在多个项目中
4、在一个boost asio tcp服务器中,怎么办能捕获客户端断线
你用的是什么服务器,我用的小鸟云服务器,没有出现这个问题。
5、boost:asio很烂吗
于来User言Boost/STL库四种风格自
第种风格Lib风格提供功能主使用般as-is例PoolGraphIntervalChronoASIO等接口使用两部第阶段型别特化第二阶段基于运行接口STLBoost部库都风格容易使用使用频率高风格
第二种风格语糖类Boost.Foreach等都属于类STL非罕见语言已经充升级
第三种风格范式论拓展即C++模拟其编程范式论例spiritlambdaproto严格说boost.mpl归属类类库使用式两步第步定制言第二步使用言类应用面向库发者所STL难见
第四类风格元编程利用模板宏进行编译器推导实现代码展、选择编译等工作典型例Boost.PPSTL/Boost.TypeTraitsenable_if等部于般用户用STL部基础元编程支持(例Traits)
STL数面向般程序员所第种库居Boost包含全部四类库风格
6、用boost asio可以实现同时处理支持上万的连接否
boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈内不容上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介绍如何写一个简单的通信程序来告诉读者如何
7、boost.asio 能开发游戏服务器吗
所以io_servie最佳应该和CPU的核数相同。
3.io_service是一个工作队列的模型:work对象来守护io_service,降低响应时延。但是每个io_servie:。在使用过程中一般有如下几个需要注意的地方:
run函数在io事件完成后会退出:1,io_servie应该尽量多,这样可以使其epoll_wait占用的时间片最多,这样可以最大限度的响应IO事件:io_service::io_service:linux下boost asio并行开发。
boost:run占用一个线程::asio。
解决这个问题的方法是通过一个asio:.三种使用方式
1)single thread single io_service, 最简单. multi io_service.
这三个性能是依次递增的。
2.在使用ASIO时:work work(io)。这样,即使所有io任务都执行完成,也不会退出,继续等待新的io任务, 性能最一般
2)multithread single io_service
3)io_service per thread,常见的方式是给其分配一个线程,然后执行run函数。但run函数在io事件完成后会退出,线程会终止,后续基于该对象的异步io任务无法得到调度::io_service io;
boost::asio:,导致后续基于该对象的异步io任务无法执行。
由于io_service并不会主动常见调度线程,需要我们手动分配
8、怎样使用Boost Asio建立非凡的客户端和服务端应用
boost/asio库中封装了抄很多关于scoket的函数,当然,asio库还包含很多底层的库。 我们可以用socket编写一个基于UDP协议的黑框通讯程序。 要想使用asio里面的函数,大多都需要先创建一个io_service对象,然后通过这个serveice来构造不同的对象
9、为什么 boost.asio 会在 linux 平台上使用 proactor
linux下boost asio并行开发:1.三种使用方式
1)single thread && single io_service, 最简单, 性能最一般
2)multithread && single io_service
3)io_service per thread. multi io_service.
这三个性能是依次递增的。
2.在使用ASIO时,io_servie应该尽量多,这样可以使其epoll_wait占用的时间片最多,这样可以最大限度的响应IO事件,降低响应时延。但是每个io_servie::run占用一个线程,所以io_servie最佳应该和CPU的核数相同。
3.io_service是一个工作队列的模型。在使用过程中一般有如下几个需要注意的地方:
run函数在io事件完成后会退出,导致后续基于该对象的异步io任务无法执行。
由于io_service并不会主动常见调度线程,需要我们手动分配,常见的方式是给其分配一个线程,然后执行run函数。但run函数在io事件完成后会退出,线程会终止,后续基于该对象的异步io任务无法得到调度。
解决这个问题的方法是通过一个asio::io_service::work对象来守护io_service。这样,即使所有io任务都执行完成,也不会退出,继续等待新的io任务。
boost::asio::io_service io;
boost::asio::io_service::work work(io);
io.run();
10、boost asio socket 服务端 底层是不是 iocp
boost asio socket 服务端 底层来是不是 iocp
ACE底层是C风格的自OS适配层,上一层基于C++的wrap类,再上一层是一些框架(Accpetor, Connector,Reactor,Proactor等),最上一层是框架上服务。
Boost.ASIO与之类似,底层是OS的适配层,上一层一些模板类,再上一层模板类的参数化(TCP/UDP),再上一层是服务,它只有一种框架为io_service。
livevent在不同的操作系统下,做了多路复用模型的抽象,可以选择使用不同的模型,通过事件函数提供服务