当前位置: 代码迷 >> 综合 >> TcpClient
  详细解决方案

TcpClient

热度:42   发布时间:2023-12-08 15:53:08.0

TcpServer表示服务端,那么TcpClient表示的就是客户端。

TcpClient::TcpClient(EventLoop* loop,const InetAddress& serverAddr,const string& nameArg): loop_(CHECK_NOTNULL(loop)),connector_(new Connector(loop, serverAddr)),name_(nameArg),connectionCallback_(defaultConnectionCallback),messageCallback_(defaultMessageCallback),retry_(false),connect_(true),nextConnId_(1)
{connector_->setNewConnectionCallback(std::bind(&TcpClient::newConnection, this, _1));// FIXME setConnectFailedCallbackLOG_INFO << "TcpClient::TcpClient[" << name_<< "] - connector " << get_pointer(connector_);
}TcpClient::~TcpClient()
{LOG_INFO << "TcpClient::~TcpClient[" << name_<< "] - connector " << get_pointer(connector_);TcpConnectionPtr conn;bool unique = false;{MutexLockGuard lock(mutex_);unique = connection_.unique();conn = connection_;}if (conn){assert(loop_ == conn->getLoop());// FIXME: not 100% safe, if we are in different threadCloseCallback cb = std::bind(&detail::removeConnection, loop_, _1);loop_->runInLoop(std::bind(&TcpConnection::setCloseCallback, conn, cb));if (unique){conn->forceClose();}}else{connector_->stop();// FIXME: HACKloop_->runAfter(1, std::bind(&detail::removeConnector, connector_));}
}

TcpClient通过Connector建立连接,关于Connector参看之前的博客。并向Connector注册连接建立后的回调函数TcpClient::newConnection()。

void TcpClient::newConnection(int sockfd)
{loop_->assertInLoopThread();InetAddress peerAddr(sockets::getPeerAddr(sockfd));char buf[32];snprintf(buf, sizeof buf, ":%s#%d", peerAddr.toIpPort().c_str(), nextConnId_);++nextConnId_;string connName = name_ + buf;InetAddress localAddr(sockets::getLocalAddr(sockfd));// FIXME poll with zero timeout to double confirm the new connection// FIXME use make_shared if necessaryTcpConnectionPtr conn(new TcpConnection(loop_,connName,sockfd,localAddr,peerAddr));conn->setConnectionCallback(connectionCallback_);conn->setMessageCallback(messageCallback_);conn->setWriteCompleteCallback(writeCompleteCallback_);conn->setCloseCallback(std::bind(&TcpClient::removeConnection, this, _1)); // FIXME: unsafe{MutexLockGuard lock(mutex_);connection_ = conn;}conn->connectEstablished();
}void TcpClient::removeConnection(const TcpConnectionPtr& conn)
{loop_->assertInLoopThread();assert(loop_ == conn->getLoop());{MutexLockGuard lock(mutex_);assert(connection_ == conn);connection_.reset();}loop_->queueInLoop(std::bind(&TcpConnection::connectDestroyed, conn));if (retry_ && connect_){LOG_INFO << "TcpClient::connect[" << name_ << "] - Reconnecting to "<< connector_->serverAddress().toIpPort();connector_->restart();}
}

TcpClient的建立连接的回调函数和TcpServer的建立连接的回调函数相似,都是通过创建一个表示连接的TcpConnection对象,并设置相关的回调函数,比较大的一个区别是在TcpClient注册的关闭回调中,会判断是否需要重连,如果需要重连,那么会重新建立连接。

void TcpClient::connect()
{// FIXME: check stateLOG_INFO << "TcpClient::connect[" << name_ << "] - connecting to "<< connector_->serverAddress().toIpPort();connect_ = true;connector_->start();
}void TcpClient::disconnect()
{connect_ = false;{MutexLockGuard lock(mutex_);if (connection_){connection_->shutdown();}}
}void TcpClient::stop()
{connect_ = false;connector_->stop();
}

建立连接,断开连接和关闭连接。