Ace Reactor的handle_close无法在连接中断的时候回调
使用一个Acceptor侦听一个端口,等待接入,当接入一个连接后,创建一个Client对象处理这个连接上的事务,
后来对端直接退出去了,本端的handle_close事件没有被触发,导致无法清理,可能是什么原因? tcp中对方强行中断连接,服务方收不到关闭连接的请求,所以不知道对方已经退出了。第二册书上有讲过这个问题,可以用timer queue来解决,定期查看对方的情况,如果长时间没有读写请求(reactor派发),可以认为对方已经退出了,主动关闭连接。 这个问题看来只能通过握手来保证了,谢谢了
另外还有一个在发送数据过程中连接突然中断的问题
我创建了一个ACE_TP_Reactor作为实现的Reactor对象,将一个Client的Read_Mask和Write_Mask注册到这个Reactor上,发送数据使用了一个队列缓冲,当要发数据时加到这个队列里去,如果在加之前队列是空的,就调用Register_Handler把Write_Mask注册上,当handle_output被触发时,仅当队列的数据全部发送完才返回-1,在handle_close过滤了WRITE_MASK。问题是,当我发到一定数量(这个数量是随机的)时,handle_output就没有触发,接着就发现连接中断了,而且handle_close也没有触发,只是对端有重连机制,才知道连接中断过了。
请问这可能是什么原因。谢谢了 网络原因?这是可能的 可以看到客户端代码么,在收到什么样的错误后重连?
我对底层的缓冲机制也不是特别清楚,你这种情况好像是每当客户端read时,reactor派发handle_output,一次性的把对列里的所有数据发过去。这样有可能造成一次发送太多,某个缓冲区满就会出问题。
可以控制一下每次发送量的上限试一下。
原来是线程互斥的问题
经过大量测试后发现,直接在handle_output里一直循环使用send或send_n发送数据是不会出现tcp断的问题。代码中使用了消息缓冲队列,代码类似如下
int CClientService::handle_output(...)
{
//读消息队列
//此处增加一个自动线程锁 AutoThreadMutex
while(!this->m_Message.Queue.IsEmpty())
{
Frame* pFrame = this->m_Message_Queue.pop();
int nSize = this->m_sock.send_n(pFrame, pFrame->len());
//其它操作
}
return -1;
}
int ClientService::SendData(void* pData, uint32 length)
{
//写消息队列
Frame * pFrame = new Frame(pData, length);
...
//此处增加一个自动线程锁 AutoThreadMutex
bool bIsEmpty = this->m_Message_Queue.IsEmpty();
m_Message_Queue.AddTail(pFrame);
...
if (bIsEmpty)
{
//注册写事件
this->reactor()->register_handle(this, ACE_Reactor_Mask::Write_Mask);
}
return length;
}
由于SendData是一个对外接口函数,可能会在多个线程中调用,由于没有对m_Message_Queue进行访问控制,导致的互斥,但还不清楚为什么会导致连接中断。
但只需要在这两个函数入口增加一个自动线程锁就解决了这个问题。
页:
[1]