peakzhang 发表于 2007-12-18 23:43:25

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

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

peakzhang 发表于 2007-12-18 23:43:34

移除事件注册

关闭相应的流对象

。。。

peakzhang 发表于 2007-12-18 23:43:51

这是我的实现代码:

1〉dll对外提供的接口函数代码

int __stdcall DisConnect( long nConn )
{

if( !find_connection(nConn) )return 0; //确认是否存在连接

Connector *connector_=(Connector *)nConn; //转换为指针
connector_->reactor()->remove_handler(connector_->get_handle(),
ACE_Event_Handler::ALL_EVENTS_MASK);

return 0;
}


2〉ACE_Event_Handler::handle_close代码

int Connector::handle_close (ACE_HANDLE h, ACE_Reactor_Mask mask)
{
ACE_DEBUG((LM_DEBUG, "handle_close\n"));

if(mask == ACE_Event_Handler::WRITE_MASK)
return 0;

::SendMessage(m_hPeerWnd, MSG_CONN_BROKEN, 0, (LPARAM)this); //通知应用层断开连接

mask = ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL;
//
//this->reactor()->remove_handler(this, mask);
this->sock_.close();                                       //客户端的ACE_SOCK_Stream
delete this;
delete_connection((long)this);                           //从连接列表中删除
return 0;//ACE_Event_Handler::handle_close(h, mask);
}

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

peakzhang 发表于 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);

行不行

peakzhang 发表于 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!

peakzhang 发表于 2007-12-18 23:44:22

这是我的客户端头文件定义:

classConnector : public ACE_Event_Handler
{
public:
Connector();
virtual ~Connector();

int open (const ACE_INET_Addr &listen_addr);

// Get this handler's I/O handle.
virtual ACE_HANDLE get_handle (void) const
    { return this->sock_.get_handle (); }

// Called when a connection is ready to accept.
virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);
int handle_output(ACE_HANDLE);

// Called when this handler is removed from the ACE_Reactor.
virtual int handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask);

ACE_SOCK_Stream sock(void) const
{ return sock_; }


HWND m_hOwnerWnd;

ACE_thread_t *m_pthreadID;
protected:
ACE_SOCK_Connector connector_;
ACE_SOCK_Stream sock_;
};


m_pthreadID是后来增加的,另外有一个全局的vector存放每次连接服务器的连接变量,即上面这个类的实例变量,请问这样的客户端怎么主动关闭?

peakzhang 发表于 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);

peakzhang 发表于 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);

peakzhang 发表于 2007-12-18 23:44:50

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

demon 发表于 2007-12-19 10:49:39

咋解决的?
给大家说下啊。
页: [1] 2
查看完整版本: 如何正常关闭ACE_Event_Handler的客户端?