返回列表 发帖

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

我把ACE_Event_Handler继承后,VC环境下封装成了客户端的DLL,用来实现发送、接收、断开连接三个功能,但是不管怎么处理,都无法在主动关闭(VB环境,直接调用“断开连接”功能)情况下,正常关闭连接(总是出现崩溃或内存错误),请问该怎么处理?能给一份正确参考代码吗?

移除事件注册

关闭相应的流对象

。。。

TOP

这是我的实现代码:

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. }
复制代码

上述代码在断开连接时严重崩溃,实在不晓得怎么回事?

TOP

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

改为

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

行不行

TOP

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!

TOP

这是我的客户端头文件定义:
  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存放每次连接服务器的连接变量,即上面这个类的实例变量,请问这样的客户端怎么主动关闭?

TOP

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

改为

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

TOP

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

改为

reactor()->remove_handler(this,
  ACE_Event_Handler::ALL_EVENTS_MASK);

TOP

呵!终于解决了!都是线程惹的祸。

TOP

咋解决的?
给大家说下啊。

TOP

返回列表