找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 6193|回复: 9

请教一个关于handle_output的问题

[复制链接]
发表于 2007-12-15 22:16:34 | 显示全部楼层 |阅读模式
使用reactor的时候,如果socket上有数据可读,会回调handle_input方法,这个很好理解,在handle_input中recv即可。 问题是是不是socket可写的情况下,就会回调handle_output?如果我在handle_output中并不作真正的send操作,岂不是handle_output会一直被回调?
 楼主| 发表于 2007-12-15 22:16:52 | 显示全部楼层
回答这个问题,得结合reactor到底使用什么实现,是Select_Reactor,还是ACE_WFMO_Reactor,两者触发机制有差别。下面是ACE程序员指南的描述,
Select是水平触发机制,socket如果可写,select就总是标记可写,直到不再可写为止。
WFMO_Reactor是边缘触发机制,事件在当前状态发生变化时触发,可写事件在socket从不可写变成可写状态时候记下。
结合ACE的Reactor框架,是否继续调用handle_output,和几个因素有关,
1、如果你在handle_output里面返回的时候,返回值置为>=0,则会继续回调。返回-1会引发调用handle_close();
2、如果是Select_Reactor,因为可写,会继续调用
3、如果是ACE_WFMO_Reactor,则需要等待内核的通知才调用。

简单一点,你可以用Reactor框架中的socket,一直写,直到不能写了,就注册写通知,等待调用handle_output(),然后继续发送直到结束为止。

这里面的东西比较微妙,如果不明白,需要自己动手调试才能体会。毕竟Reactor也是ACE里面的一大框架体系,还是比较复杂的。个人之见,仅供参考,如有疑问,大家一起讨论。
 楼主| 发表于 2007-12-15 22:17:01 | 显示全部楼层
谢谢版主的答复。
我用的是基于select实现的reactor,我的主要问题是:如果我没有那么多的数据要写,那我的handle_output里面能干什么呢?
讨论下面的一个应用场景应该能说的清楚一些:
背景:我需要实现一个服务器,可以同时接受多个客户端的请求,服务器端根据请求进行一些后台处理,比如查询数据库,然后将查询结果返回给客户端。
问题:
1、在上面的场景中,服务端只有在执行查询完成后,才会有数据要写,这个写操作能不能不能放在handle_output中?
2、因为服务端需要同时处理多个socket连接,我是不是需要用多个ACE_Svc_Handler对象?另外,假如我在服务端使用一个线程池来处理客户端的请求,当一个请求处理完成后,我如果知道该在哪个ACE_Svc_Handler对象的handle_output中来执行写操作?
3、俺刚学习ace,望不吝赐教。
 楼主| 发表于 2007-12-15 22:17:09 | 显示全部楼层
1、写操作可以放在任何地方,视程序需要,比如handle_input()中作出反馈。handle_output一般可以用来发送上次没发完的内容(进行队列缓冲)
2、默认是一个连接对,一个ACE_Svc_Handler对象,管理起来比较容易。这个和线程池无关,ACE框架自动的帮你分开了,只关心这个连接处理对象的处理就可以了。你必须亲自写一下,才能明白ACE封装的有多好,到底是怎么回事。
3、大家一起进步。

good luck.
 楼主| 发表于 2007-12-15 22:17:28 | 显示全部楼层
这个我也很纳闷,就是一个服务器接受一个请求(handle_input),响应的时候
我就使用(handle_output) 去处理,我这样在(handle_input) 需要注册
一个事件处理器,我就注册 this,但是这样 reactor 会报错
 楼主| 发表于 2007-12-15 22:17:40 | 显示全部楼层
winston 版主,您好;

 对于因素的第1点;如果返回>=0会继续回调,而-1会主动关闭socket,这样的情况下是否就无法维持client的长连接了;如果想做到:在不断开client的长连接情况下,成功调用一次handle_output()后,就继续调用handle_input()进行数据的接收与处理;这样大概需要怎样实现呢?

 我是初学者,这个问题一直困扰着我,还望不啻指教,谢谢:)
发表于 2008-6-7 13:32:47 | 显示全部楼层
怎么讨论没有了?这个也正是困扰我的地方!请高手续哦
发表于 2008-6-13 18:03:34 | 显示全部楼层
windows平台默认的是ACE_WFMO_Reactor,如果自己没设的话,就是ACE_WFMO_Reactor。想用Select_Reactor,别忘了自己设置。
发表于 2008-8-23 18:05:26 | 显示全部楼层
当你需要发送数据的时候,一般把数据放到一个队列里,并注册写事件,等待handle_output回调,在handle_output里进行发送操作,直到数据发送完就返回-1,如果数据没有发送完出现了其它问题就返回0,因为Reactor的机制当handle_x返回-1时,会自动回调handle_close,这个时候就需要在handle_close处理的时候进行判断,判断传入的close_mask是否是write_mask,如果是的话,就不要继续执行清理工作,只是简单的返回0表示继续使用这个连接
发表于 2008-9-17 10:22:39 | 显示全部楼层
问题:我注册了一个UDP Socket句柄, 运行反应器, 可是调试时发现怎么也调不到handle_output.不知道这时为什么?请高手赐教
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-23 00:02 , Processed in 0.015027 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表