找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 9755|回复: 11

如何正常关闭ACE_Event_Handler的客户端?

[复制链接]
发表于 2007-12-18 23:43:25 | 显示全部楼层 |阅读模式
我把ACE_Event_Handler继承后,VC环境下封装成了客户端的DLL,用来实现发送、接收、断开连接三个功能,但是不管怎么处理,都无法在主动关闭(VB环境,直接调用“断开连接”功能)情况下,正常关闭连接(总是出现崩溃或内存错误),请问该怎么处理?能给一份正确参考代码吗?
 楼主| 发表于 2007-12-18 23:43:34 | 显示全部楼层
移除事件注册

关闭相应的流对象

。。。
 楼主| 发表于 2007-12-18 23:43:51 | 显示全部楼层
这是我的实现代码:

1〉dll对外提供的接口函数代码
  1. int __stdcall DisConnect( long nConn )
  2. {
  3. if( !find_connection(nConn) )return 0; //确认是否存在连接
  4. Connector *connector_=(Connector *)nConn; //转换为指针
  5. connector_->reactor()->remove_handler(connector_->get_handle(),
  6.   ACE_Event_Handler::ALL_EVENTS_MASK);
  7. return 0;
  8. }
  9. 2〉ACE_Event_Handler::handle_close代码
  10. int Connector::handle_close (ACE_HANDLE h, ACE_Reactor_Mask mask)
  11. {
  12. ACE_DEBUG((LM_DEBUG, "[Connector::handle_close]handle_close\n"));
  13. if(mask == ACE_Event_Handler::WRITE_MASK)
  14.   return 0;
  15. ::SendMessage(m_hPeerWnd, MSG_CONN_BROKEN, 0, (LPARAM)this); //通知应用层断开连接
  16. mask = ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL;
  17. //
  18. //this->reactor()->remove_handler(this, mask);
  19. this->sock_.close();                                       //客户端的ACE_SOCK_Stream
  20. delete this;
  21. delete_connection((long)this);                             //从连接列表中删除
  22. return 0;//ACE_Event_Handler::handle_close(h, mask);
  23. }
复制代码
上述代码在断开连接时严重崩溃,实在不晓得怎么回事?
 楼主| 发表于 2007-12-18 23:44:00 | 显示全部楼层
把connector_->reactor()->remove_handler(connector_->get_handle(),
  ACE_Event_Handler::ALL_EVENTS_MASK);

改为

connector_->reactor()->remove_handler(connector,
  ACE_Event_Handler::ALL_EVENTS_MASK);

行不行
 楼主| 发表于 2007-12-18 23:44:07 | 显示全部楼层
I can guess two cases.
1. handle_close be called twice
2. handler is used, after handle_close.
Comment out delete this, try it with logging on, then check the logs.
BTW,
You better refactor this code anyway.It's buggy.
Good luck!
 楼主| 发表于 2007-12-18 23:44:22 | 显示全部楼层
这是我的客户端头文件定义:
  1. class  Connector : public ACE_Event_Handler  
  2. {
  3. public:
  4. Connector();
  5. virtual ~Connector();
  6. int open (const ACE_INET_Addr &listen_addr);
  7. // Get this handler's I/O handle.
  8. virtual ACE_HANDLE get_handle (void) const
  9.     { return this->sock_.get_handle (); }
  10. // Called when a connection is ready to accept.
  11. virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);
  12. int handle_output(ACE_HANDLE);
  13. // Called when this handler is removed from the ACE_Reactor.
  14. virtual int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask);
  15. ACE_SOCK_Stream sock(void) const
  16. { return sock_; }
  17. HWND m_hOwnerWnd;
  18. ACE_thread_t *m_pthreadID;
  19. protected:
  20. ACE_SOCK_Connector connector_;
  21. ACE_SOCK_Stream sock_;
  22. };
复制代码
m_pthreadID是后来增加的,另外有一个全局的vector存放每次连接服务器的连接变量,即上面这个类的实例变量,请问这样的客户端怎么主动关闭?
 楼主| 发表于 2007-12-18 23:44:30 | 显示全部楼层
把connector_->reactor()->remove_handler(connector_->get_handle(),
  ACE_Event_Handler::ALL_EVENTS_MASK);

改为

reactor()->remove_handler(connector,
  ACE_Event_Handler::ALL_EVENTS_MASK);
 楼主| 发表于 2007-12-18 23:44:36 | 显示全部楼层
把connector_->reactor()->remove_handler(connector_->get_handle(),
  ACE_Event_Handler::ALL_EVENTS_MASK);

改为

reactor()->remove_handler(this,
  ACE_Event_Handler::ALL_EVENTS_MASK);
 楼主| 发表于 2007-12-18 23:44:50 | 显示全部楼层
呵!终于解决了!都是线程惹的祸。
发表于 2007-12-19 10:49:39 | 显示全部楼层
咋解决的?
给大家说下啊。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

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

GMT+8, 2025-3-12 15:07 , Processed in 0.022288 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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