在muduo中只有一种连接断开方式,就是被动关闭,也就是套接字上read返回0.(当然现在也加上了主动关闭),本文探讨被动关闭的流程。
首先TcpConnection::handleRead中,如果read 返回0,去执行handleClose。
void TcpConnection::handleRead(Timestamp receiveTime)
{
loop_->assertInLoopThread();
int savedErrno = 0;
ssize_t n = inputBuffer_.readFd(channel_->fd(), &savedErrno);
if (n > 0)
{
messageCallback_(shared_from_this(), &inputBuffer_, receiveTime);
}
else if (n == 0)
{
handleClose();
}
else
{
errno = savedErrno;
LOG_SYSERR << "TcpConnection::handleRead";
handleError();
}
}
由于每个连接有一个连接套接字,在连接断开前,套接字对应的channel还在poller的关注列表中,所以handleClose需要将当前channel对象的所有事件取消关注。由于TcpConnection中的closeCallback_主要是给TcpServer 和TcpClient使用,用来通知他们移除持有的TcpConnectionPtr,所以handleclose然后调用closeCallback_。
void TcpConnection::handleClose()
{
loop_->assertInLoopThread();
LOG_TRACE << "fd = " << channel_->fd() << " state = " << stateToString();
assert(state_ == kConnected || state_ == kDisconnecting);
// we don't close fd, leave it to dtor, so we can find leaks easily.
setState(kDisconnected);
channel_->disableAll();
TcpConnectionPtr guardThis