淺析淘寶網絡通信庫tbnet的實現

最近開始看Tair的源碼實現,Tair的通信使用的是淘寶的開源的網絡庫tbnet實現。具體來說是依靠tbnet::Transport類型實現,其源代碼路徑如下:
http://code.taobao.org/svn/tb-common-utils/trunk/tbnet/src


下面介紹其通信流程:

1. 啓動
Transport::start()完成其啓動,主要工作是啓動了兩個線程:_readWriteThread和_timeoutThread. 這兩個線程的實際入口函數式Tranport::run(), 下面是Transport::run的實現:

點擊(此處)摺疊或打開

  1. void Transport::run(tbsys::CThread *thread, void *arg) {
  2.     if (thread == &_timeoutThread) {
  3.         timeoutLoop();
  4.     } else {
  5.         eventLoop((SocketEvent*)arg);
  6.     }
  7. }
    A. 讀寫線程:
        1. 讀寫線程使用epoll實現,在Transport中存在一個EPollSocketEvent _socketEvent 成員變量, arg傳入的是這個成員變量的指針,EPollSocketEvent是epoll個操作的封裝,在EPollSocketEvent的構造函數中會調用epoll_create初始化epoll。
        2. eventLoop的實現步驟如下:
                a.  調用socketEvent->getEvents() 取得發生的事件並放入到ioevents數組中
                        i.  調用epoll_wait等待讀寫事件;
                        ii. 每個事件的events[i].data.ptr存放有事件對應的IOComonet(socket 封裝),可以用來處理讀寫事件;
                b.  對於讀寫事件,分別調用ioc->handleReadEvent()和ioc->handleWriteEvent()處理;
    
    B. timeout線程
        1. 主要用於檢查通信的socket是否超過一定時常沒有使用,對於TCPComponent(封裝通信socket),如果15分鐘沒有使用,則斷開連接;

2. 監聽
通過調用Transport::listen()完成監聽, 主要完成以下步驟:
    a.  創建TCPAcceptor,繼承於IOComonet(socket 封裝),並啓動異步監聽;
    b. 調用addComponent(acceptor, true, false);
            i.  創建epoll_event ev,設置ev.data.ptr = socket->getIOComponent(),用來處理讀寫事件的IOComponentsocket 封裝)
            ii. 調用epoll_ctl(_iepfd,EPOLL_CTL_ADD,socket->getSocketHandle(),&ev)註冊監聽socket上的讀取事件;
    c. 當客戶端有connect請求過來的時候會觸發監聽socket上的讀取事件,TCPAcceptor::handleReadEvent()會被調用。

3. 接受客戶端的連接請求
系統在TCPAcceptor::handleReadEvent()中接受客戶端的連接請求,主要步驟如下:
    a. socket = ((ServerSocket*)_socket)->accept() 接受連接請求並得到通信socket;
    b. 創建TCPComponent封裝通信socket;
    c. 調用addComponent(component, true, false) 註冊當前socket的讀取事件。

4. 數據通信
    A. 數據讀取
         數據通信由通信socket完成,該socket在epoll中註冊,當有數據需要讀取的時候會觸發讀取事件並調用TCPComponent::handleReadEvent()處理。
    B. 數據發送
         當有數據需要發送時Connection::postPacket()函數, 這個函數中會調用_iocomponent->enableWrite(true),註冊寫入事件,並調用TCPComponent::handleWriteEvent()處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章