muduo之TcpClient
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                muduo之TcpClient
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                ? ? ? ? ? muduo用TcpClient發起連接,TcpClient有一個Connector連接器,TCPClient使用Conneccor發起連接, 連接建立成功后, 用socket創建TcpConnection來管理連接, 每個TcpClient class只管理一個TcpConnecction,連接建立成功后設置相應的回調函數。很顯然,TcpClient用來管理客戶端連接,真正連接交給Connector。
TcpClient.h
// Copyright 2010, Shuo Chen. All rights reserved. // http://code.google.com/p/muduo/ // // Use of this source code is governed by a BSD-style license // that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com) // // This is a public header file, it must only include public header files.#ifndef MUDUO_NET_TCPCLIENT_H #define MUDUO_NET_TCPCLIENT_H#include "muduo/base/Mutex.h" #include "muduo/net/TcpConnection.h"namespace muduo { namespace net {class Connector; typedef std::shared_ptr<Connector> ConnectorPtr;//TCPClient使用Conneccor發起連接, 連接建立成功后, 用socket創建TcpConnection來管理連接, 每個TcpClient class只管理一個TcpConnecction class TcpClient : noncopyable {public:// TcpClient(EventLoop* loop);// TcpClient(EventLoop* loop, const string& host, uint16_t port);TcpClient(EventLoop* loop,const InetAddress& serverAddr,const string& nameArg);~TcpClient(); // force out-line dtor, for std::unique_ptr members.void connect();void disconnect();void stop();TcpConnectionPtr connection() const{MutexLockGuard lock(mutex_);return connection_;}EventLoop* getLoop() const { return loop_; }bool retry() const { return retry_; }void enableRetry() { retry_ = true; }const string& name() const{ return name_; }/// Set connection callback./// Not thread safe.void setConnectionCallback(ConnectionCallback cb){ connectionCallback_ = std::move(cb); }/// Set message callback./// Not thread safe.void setMessageCallback(MessageCallback cb){ messageCallback_ = std::move(cb); }/// Set write complete callback./// Not thread safe.void setWriteCompleteCallback(WriteCompleteCallback cb){ writeCompleteCallback_ = std::move(cb); }private:/// Not thread safe, but in loopvoid newConnection(int sockfd);/// Not thread safe, but in loopvoid removeConnection(const TcpConnectionPtr& conn);EventLoop* loop_; //用戶創建傳入的EventLoopConnectorPtr connector_; // avoid revealing Connector //指向Connector的shared_ptrconst string name_; //用戶指定的名字//這些回調函數都需要顯示設置ConnectionCallback connectionCallback_; //連接建立回調函數MessageCallback messageCallback_; //消息到來回調函數WriteCompleteCallback writeCompleteCallback_; //數據發送完畢回調函數 bool retry_; // atomic //連接斷開后是否重連bool connect_; // atomic// always in loop threadint nextConnId_; //name_+nextConnId_用于標識一個連接mutable MutexLock mutex_;TcpConnectionPtr connection_ GUARDED_BY(mutex_); };} // namespace net } // namespace muduo#endif // MUDUO_NET_TCPCLIENT_HTcpClient.cc
// Copyright 2010, Shuo Chen. All rights reserved. // http://code.google.com/p/muduo/ // // Use of this source code is governed by a BSD-style license // that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com) //#include "muduo/net/TcpClient.h"#include "muduo/base/Logging.h" #include "muduo/net/Connector.h" #include "muduo/net/EventLoop.h" #include "muduo/net/SocketsOps.h"#include <stdio.h> // snprintfusing namespace muduo; using namespace muduo::net;// TcpClient::TcpClient(EventLoop* loop) // : loop_(loop) // { // }// TcpClient::TcpClient(EventLoop* loop, const string& host, uint16_t port) // : loop_(CHECK_NOTNULL(loop)), // serverAddr_(host, port) // { // }namespace muduo { namespace net { namespace detail {void removeConnection(EventLoop* loop, const TcpConnectionPtr& conn) {loop->queueInLoop(std::bind(&TcpConnection::connectDestroyed, conn)); }void removeConnector(const ConnectorPtr& connector) {//connector-> }} // namespace detail } // namespace net } // namespace muduoTcpClient::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的連接回調函數設置為TcpClient::newConnection//該函數在Connector::handleWrite中被調用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_));} }void TcpClient::connect() {// FIXME: check stateLOG_INFO << "TcpClient::connect[" << name_ << "] - connecting to "<< connector_->serverAddress().toIpPort();connect_ = true;//調用Connector::start,發起連接connector_->start(); }void TcpClient::disconnect() {connect_ = false;{MutexLockGuard lock(mutex_);if (connection_){connection_->shutdown();}} }void TcpClient::stop() {connect_ = false;connector_->stop(); }//新連接的回調函數,將新連接封裝為TcpConnection交給TcpClient來管理 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 necessary//創建一個堆上局部TcpConnection對象,并用TcpClient的智能指針connection_保存起來TcpConnectionPtr 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_);//將新創建的TcpConnection賦給TcpClient類內成員connection_connection_ = conn;}conn->connectEstablished(); }void TcpClient::removeConnection(const TcpConnectionPtr& conn) {loop_->assertInLoopThread();assert(loop_ == conn->getLoop());{MutexLockGuard lock(mutex_);assert(connection_ == conn);connection_.reset(); //重置}//I/O線程中銷毀loop_->queueInLoop(std::bind(&TcpConnection::connectDestroyed, conn));if (retry_ && connect_) //是否發起重連{LOG_INFO << "TcpClient::connect[" << name_ << "] - Reconnecting to "<< connector_->serverAddress().toIpPort();//這里的重連是連接成功后斷開的重連,所以實際上是重啟connector_->restart();} }?
總結
以上是生活随笔為你收集整理的muduo之TcpClient的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: muduo之TimerQueue
 - 下一篇: muduo之Connector