yaoxing25 发表于 2009-5-26 23:44:30

关于ACE_Reactor的问题(救命。。。)

各位大侠救命呀:
       最近在使用ACE编写一个网络连接,大致是这样的。
我要写的是一个客户端主要功能是连接主机设备。现在的设计是使用ACE_Reactor 模式。
class CSoftcoClient : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
{
public:
Request_Handler(ACE_Thread_Manager *thr_mgr = 0);
protected:
virtual int handle_input(ACE_HANDLE fd = ACE_INVALID_HANDLE);

virtual int open (const ACE_INET_Addr &local_addr);

virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE);

virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
                            ACE_Reactor_Mask = 0);

virtual int handle_timeout(ACE_HANDLE = ACE_INVALID_HANDLE,
                            ACE_Reactor_Mask = 0);
private:
static Task_Manager task_mgr;
};
1、上面是我的一个client 类,我通过一个线程来发起连接,在每次连接时直接new一个client指针来发起连接。当我删除设备时是使用client->peer()->close()方法,可以直接回调handle_close()方法。在handle_timeout方法时我也会判断与设备的连接时间是否超时如果超时也是设备handle_close()方法来释放client指针。在直接使用ACE_Reactor时由于默认只能连接62台设备,这里所有的操作都是成功的。但是我的系统性能要求要连接800台设备。
2、使用ACE_Select_Reactor将ACE_Reactor的连接62个限制取消,但是这时候就会出现我发送消息成功,接收消息超时的情况. 导致我系统的相应功能都会超时.我想知道ACE_Select_Reactor在使用的时候需要注意哪些地方, 为什么我使用ACE_Reactor时可以正常工作,而使用了ACE_Select_Reactor就会出现超时的情况。我对代码进行了调试同时还发现了,在我删除设备时client->peer()->close()执行完了,不再调用handle_close()方法,同样的情况在handle_timeout()里也出现了,真的不知道是哪里出了问题。
3、今天还尝试了使用ACE_TP_Reactor来替代ACE_Select_Reactor对ACE_Reactor进行初始化,使用同样的操作,发现ACE_TP_Reactor的方式只能连接62台设备,书上说ACE_TP_Reactor可以解决ACE_Reactor只能连接62的问题,可是我试了怎么还是连接62台?
希望高手指点一下。不胜感激!~!!~!!~!

[ 本帖最后由 yaoxing25 于 2009-5-27 00:59 编辑 ]

yaoxing25 发表于 2009-5-28 21:04:38

回复 #1 yaoxing25 的帖子

怎么没人来指点一下呀,急用呀,要不版主来看一下,帮忙看看有什么好的建议!我看了很多帖子版本都有办法解决的。

现在这个问题 已经花了我四天了也没有头绪,网上对这方面的资料也不是很多。。

chris_liu 发表于 2009-5-30 13:46:48

回复 #1 yaoxing25 的帖子

ACE_TP_Reactor是Select_Reactor的线程池版本,应该不会有62个设备限制吧?
ACE_Select_Reactor这些方法(handle_input/handle_output/等)都是在一个任务中调用的。
注意不要造成死锁。
关于ACE_Select_Reactor更多的内容可以看 C++网络编程第二卷

yaoxing25 发表于 2009-5-30 22:28:45

谢谢,楼上的,我后来试过了,ACE_TP_Reactor连接的问题已经解决了,现在只剩下一个问题,就是发送数据成功,但如果连接数一多就会出现接收数据超时的情况,而且是所有数据都无法接。
在ACE_Reactor中还有什么情况下会出现这种问题。

winston 发表于 2009-5-30 22:58:51

有代码有真相,没有代码,大家都是瞎猜而已。贴代码才能帮你分析分析。

yaoxing25 发表于 2009-5-31 00:26:04

我的代码实现大致上是这样的:

int Connect::InitConnect() //这是我初始化线程的方法
{
        ACE_Select_ReactorpSelectReactor;
        ACE_NEW_RETURN (pSelectReactor, ACE_Select_Reactor, -1);
        ACE_Reactor pReactor;
        ACE_NEW_RETURN (pReactor, ACE_Reactor(ACE_Select_Reactor, 1), -1);
        ACE_Reactor::instance(pReactor, 1);

        if (StartThead(pReactor)) //这里是调动一个线程来实现连接设备的,
                                                          //这里面是使用CClient的指针来实现连接的。
        {
                return -1;
        }
        return 0;
}

int CClient::open(void *p)
{
        if (acceptor_.open (local_addr) == -1) return -1;
        return reactor ()->register_handler(this, ACE_Event_Handler::ACCEPT_MASK);
}

int CClient::handle_input(ACE_HANDLE)
{
        if (收到数据)
        {
                Split(strData); //该方法是用来将收到的消息进行分割并通知上层的。
        }

        return 0;
}

int CClient::handle_timeout(ACE_HANDLE)
{
        //设定时器,如果到达定时器时间handle_input还没有收到相应的数据则超时
        this->peer()->handle_close(); //这里是可以调用的,
                                                                  //理论上调用完这个方法应该调用CClient::handle_close()
        return 0;
}

int CClient::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
{
        SVC_Handle::handle_close();//这里好像是要调用父类的handle_close(),进行释放。
       
        return 0;
}

基本上我使用的ACE_Select_Reactor就是这样的。原来是直接使用ACE_Reactor的没有出现过数据接收超时的情况,在windows平台下ACE_Reactor的默认实现类是ACE_WMFO_Reactor,我将其替换为ACE_Select_Reactor,来避免受最大62事件处理的限制,就出现的接收数据超时的情况。

winston 发表于 2009-5-31 11:58:02

READ_MASK
WRITE_MASK
处理呢?

yaoxing25 发表于 2009-5-31 21:47:39

那我好像是在open 方法里做的。

yaoxing25 发表于 2009-6-2 00:26:33

对了,我发现了,我的open()方法中没有READ_MASK这个处理,而且还可以进行数据发送和接收,这是为什么呢?而且我也没有WRITE_MASK处理。今天我试了一下,用ACE_TP_Reactor来实例化ACE_Reactor,还是会存在同样的问题,只要我的连接数达到二百左右就会出现数据接收不到的情况,好像是不再调用我的Client类的handle_input方法,是不是因为我使用了ACE_Select_Reactor和ACE_TP_Reactor来实例化ACE_Reactor时出错,而我的所有连接都是通过这个ACE_Reactor的一个指针发起的,只是不明白为什么我直接使用ACE_Reactor时为什么没有出现数据接收不到的情况,难道是因为连接数少的原因?
不好意思刚接触ACE网络编程,不懂的太多了,希望大家多帮助呀!~!!~!

yaoxing25 发表于 2009-6-7 01:18:28

经过这段时间的调试,发现了一个情况,因为我的连接是一个线程发起的,而且每个连接都由一个client指针发起,而且各个连接的数据都是由每个Client类的handle_input()方法负责接收,而且Client类是在使用前ACE_Reactor已经被ACE_Select_Recator实例化了,所以当有一个连接的handle_input方法无法接收数据,可能是ACE_Reactor异常,导致其他的连接都无法接收数据,而且这个问题的主要原因是:当一个连接正在发送数据,此时正好断连操作,将Client的指针删除,所以我现在将连接进行加锁,就不会出现这种情况了,不知道是不是我说的这个原因,有高手再帮忙分析一下。。。。。。。。。。只是现在项目还有点问题,不过已经不大了,将这个情况说出来大家一起共享,刚接触ACE网络编程还有很多不知道的情况,希望大家多多帮助。。。。。。。
页: [1] 2 3 4
查看完整版本: 关于ACE_Reactor的问题(救命。。。)