muduo TcpServer粗略過程

2022-06-19 15:27:15 字數 2632 閱讀 8868

使用 \muduo\examples\asio\chat\server.cc 作例子

首先需要知道:

eventloop:乙個事件分發器類,擁有 poller 物件,事件處理函式是 loop(),在這裡捕獲註冊的 channel 事件,並呼叫相應的**函式。

while (!quit_)

...}

下面這幾個類,都擁有乙個 eventloop * 物件,他們的事件註冊,就註冊到他們分配到的 eventloop * 物件中。

channel:乙個封裝 fd 的類,方便向 eventloop 註冊事件.比如,可讀,可寫事件。

acceptor:負責接受連線的類,擁有乙個channel物件,向 eventloop 註冊為可讀,則當有人來連線的時候,就能呼叫相應的**。

tcpconnecton:也擁有乙個 channel 物件,已建立連線以後,再生成的物件,用來處理,連線之後的操作,傳送,接受,斷開。

然後開始來看吧,客戶使用的**,極其簡單,就建立起乙個 chatserver . 這裡的 loop 為 baseloop 處於主線程的條件下。

chatserver server(&loop, serveraddr);

server.start();

loop.loop();

再來看看 server.start() 幹了什麼.先在建構函式中,初始化了幾個成員,threadpool_,acceptor_。設定了acceptor_的**.

1.threadpool_.start(),開啟建立 n 個 eventloopthread 個物件,即開了了 n 個 eventloop 物件,並執行他們的 loop() 函式。

2.loop_runinloop(..listen..),runinloop 簡單說明一下,就是保證你的函式執行的環境是跟你的 eventloop 處於同乙個執行緒中,保證同步。 最終,這個函式會呼叫 acceptor_.listen(),這個函式的本質就是向他的 loop 註冊可讀事件,可讀的話就是有人來連線啦。可以自己跟蹤下。

tcpserver::tcpserver(eventloop*loop,

const inetaddress&listenaddr,

const

string&namearg,

option option)

: loop_(check_notnull(loop)),

hostport_(listenaddr.toipport()),

name_(namearg),

acceptor_(

new acceptor(loop, listenaddr, option ==kreuseport)),

threadpool_(

neweventloopthreadpool(loop)),

connectioncallback_(defaultconnectioncallback),

messagecallback_(defaultmessagecallback),

nextconnid_(1)

void

tcpserver::start()

到這裡為止,就已經註冊了 accept fd 的可讀事件,那麼當有連線到來的時候,就會觸發,在 loop() 函式中,然後去呼叫響應的**函式,在 tcpserver 建構函式中可以看到,註冊了 acceptor_ 可讀**是 tcpserver::newconnecton() ,所以,就來看看這個函式又看了什麼。

2.註冊,響應的**函式,可讀,可寫,有連線(就是呼叫使用者設定的有連線來的**函式),關閉。

3.最後呼叫,ioloop->runinloop(boost::bind(&tcpconnection::connectestablished, conn));這個函式裡面,實際就是將 tcpconnection 中的 channel 註冊為可讀,這樣就能開始接收 client  的資料。然後也可以呼叫 tcpconnection 的 send 來發資料。

這裡的接受和傳送設計乙個 buffer 類,這是乙個 快取類,非阻塞i/o必備,這裡就不說先。

void tcpserver::newconnection(int sockfd, const inetaddress&peeraddr)

當已經建立連線好以後,我們再來看看,在最初的 loop() 函式中的 channel::handleevent() 函式.可以看到,通過判斷事件來種類,來呼叫響應的**函式。

if ((revents_ & pollhup) && !(revents_ &pollin))

if(closecallback_) closecallback_();

} if (revents_ &pollnval)

if (revents_ & (pollerr |pollnval))

if (revents_ & (pollin | pollpri |pollrdhup))

if (revents_ &pollout)

大致邏輯是這樣,服務端的過程比客戶端的過程要複雜一些,畢竟服務端要管理這麼多個連線。客戶端的過程大家可以自己去看一下。本文只是粗略的解釋了服務端的過程,其中涉及的多執行緒應該注意的事項還無功力能總結。

繪製粗虛線

以前很少畫虛線,因此不太關心繪製粗虛線該怎麼辦。最近需要用到這個功能,因此學習了一下,與大家共享。cpen類有兩個建構函式,我們經常用第乙個,而忽略了第二個。其實很多問到畫粗線時希望改變線頭的預設顯示方式,比如希望是圓弧頭而不是預設的方形頭等。都可以用這個建構函式定義的cpen物件來實現。這裡我主要...

組網粗遊記(一)

今天客串了一把網管,鼓弄了差不多有一天,好歹最後弄出了點成果可以讓我稍感欣慰。簡單來說,本次的任務就是在公司內網的基礎上拓撲出乙個三層網路結構,用來模仿現場環境,以便得到更準確的系統測試結果。上圖 上裝置 操作描述 step 1 開啟securecrt,新建會話,協議採用 serial 即串列埠 s...

VPD技術粗解

vpd技術,dba policies這張表中儲存了啟用vpd技術的表 select from dba policies where object name upper pa projects 給某張表啟用vpd 1.create data create table t x number insert...