muduo庫源碼剖析(二) 服務端

來源:互聯網
上載者:User

一. TcpServer類:

管理所有的TCP客戶串連,TcpServer供使用者直接使用,生命期由使用者直接控制。使用者只需設定好相應的回呼函數(如訊息處理messageCallback)然後TcpServer::start()即可。

主要資料成員:

boost::scoped_ptr<Accepter> acceptor_; 用來接受串連

std::map<string,TcpConnectionPtr> connections_; 用來儲存所有串連

connectonCallback_,messageCallback_,writeCompleteCallback_,用來接受使用者註冊的回呼函數

EventLoop* loop; 接受串連的事件迴圈

主要功能函數:

set*Callbak() 註冊使用者回呼函數

newconnection() 需要在建構函式內將其註冊給Acceptor,當Acceptor接受一個串連之後回調該函數。在本函數內部建立一個connection對象,並將 *Callback_註冊給建立的 Connection 對象。最後,從線程池取出一個線程做I/O線程,在該I/O線程的 EventLoop 的 runInLoop() 中傳入 TcpConnection::connectEstablished(). 因為必然不在一個線程中,在runInLoop()中調用EventLoop::quueInLoop(),將TcpConnection::connectEstablished()加入pendingFunctors.

二. Acceptor類:

負責監聽串連請求,接收串連並將新的串連返回給TcpServer。

Acceptor主要是供TcpServer使用的,其生命期由後者控制。一個Acceptor相當於持有服務端的一個listenning socket描述符,該socket可以accept多個TCP客戶串連,。

主要資料成員:

EventLoop* loop_;

Socket acceptSocket_;封裝了socket等,用來監聽

Channel acceptChannel_;Acceptor通過Channel向Poller註冊事件,EventLoop通過Channel分發回調Acceptor相應的事件處理函數。

boost::function<void(sockfd,InetAddress&)>NewConnectionCallback_ , 串連請求接收之後,通過其回調TcpServer::newconnection().

主要功能函數:

listen(),調用Socket::listen()開始監聽,同時,調用Channel::enableReading()向Poller註冊可讀事件,有資料可讀代表新來了串連請求。

handleRead(),在建構函式中將其註冊給Channel::readCallback_。當Poller發現屬於Acceptor的Channel的可讀事件時,在EventLoop中會驅動Channel::handleEvent()-->Channel::handleEventWithGuard()進行事件分發,調用readCallback回調 Acceptor::handlRead(),在其內調用Socekt::accept(),再回調TcpServer::newconnection(),將新串連的sockfd傳回給TcpServer。

服務端監聽及接受串連的流程:

向Poller註冊監聽事件的主線調用流程,TcpServer::start()-->EventLoop::runInLoop(Acceptor::listen())-->Channel::enableReading()-->Channel::update(this)-->EventLoop::updateChannel(Channel*)-->Poller::updateChannel(Channel*)

接受串連,當Poller::poll()發現有事件就緒,通過 Poller::fillActiveChannel() 將就緒事件對應的 Channel 加入 ActiveChannelList,

EventLoop::loop()-->Poller::poll()-->Poller::fillActiveChannel(),loop()-->Channel::handleEvent()->Acceptor::handleRead()->TcpServer::newConnection()->EventLoop::runInLoop(bind(&TcpConnection::connectEstablished))->EventLoop::queueInLoop()->EventLoop::loop()->EventLoop::doPendingFunctors()->TcpConnection::connectEstablished()。

三. Connection類:

用於管理一個具體的TCP客戶串連,完成使用者指定的串連回調connectionCallback。
TcpConnection構造時接收參數有TCP串連的描述符sockfd,服務端地址localAddr,用戶端地址peerAddr,並通過Socket封裝sockfd。且採用Channel管理該sockfd,

更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/cplus/

主要資料成員:

enum StateE { kDisconnected, kConnecting, kConnected, kDisconnecting };分別表示已斷開,正在串連,已串連,正在斷開。

scoped_ptr<Socket> socket_;封裝該串連的socket

scoped_ptr<Channel> channel_;串連可以通過該channel向Poller註冊該串連的讀寫等事件。串連還要向Channel註冊TcpConection的可讀/可寫/關閉/出錯系列回呼函數,用於Poller返回就緒事件後Channel::handleEvent()執行相應事件的回調。

boost::function<void()> **Callback_,在TcpServer::newconnection()中建立TcpConnection時,就會將TcpServer中的各種處理函數註冊給相應的 TcpConnection::*Callback_ 。

Buffer inputBuffer_,outputBuffer_。輸入輸出的緩衝。

主要功能函數:

handle{Read(),Write(),Close(),Error()},處理串連的各種事件,會由Channel::handleEvent()根據Poller返回的具體就緒事件分發調用相應的TcpConnection::handle**().

connectEstablished(),設定串連的狀態為kConnected,將channel_進行綁定,調用channel::enableReading()向Poller註冊讀事件,最後回調connectionCallback_會回調TcpServer中相應的回呼函數,一般會在TcpServer中繼續回調使用者傳進來的回呼函數。

send(),sendInLoop(),send()有幾個重載都是進行發生資料,send()-->sendInLoop(),後者中檢測輸出buffer中沒有資料排隊就直接寫,如果沒有寫完,或者outbuffer中有資料排隊則將資料追加到outbuffer中,然後調用channel::enableWriting()向Poller註冊寫事件。

TcpConnection::setTcpNoDelay()->socketopt(..,TCP_NODELAY..)來關閉Nagle演算法。

發送資料流程:

TcpConnection::send(string& message)->EventLoop::runInLoop(bind(&TcpConnection::sendInLoop(string& message))->EventLoop::doPendingFunctors()->TcpConnection::sendInLoop(string& message)保證訊息發送的安全執行緒,後者通過write系統調用發送訊息。

當Poller返回一個串連的可寫或者可讀就緒事件時,回調過程類似Acceptor的串連接受過程。

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。