Mudo C++網路庫第七章學習筆記
self發表於2018-10-24
muduo程式設計示例
- muduo庫是設計來開發內網的網路程式, 它沒有做任何安全方面的加強措施, 如果在公網上可能會受到攻擊;
- muduo庫把主動關閉連線這件事分成兩步來做:
- 如果主動關閉連線, 會先關本地寫端, 等對方關閉之後, 再關閉本地讀端;
muduo Buffer類的設計與使用
- muduo輸入輸出緩衝區的設計與實現;
- Unix/Linux上的五種IO模型:
- 阻塞(blocking);
- 非阻塞(non-blocking);
- IO複用(IO multiplexing);
- 訊號驅動(signal-driven);
- 非同步(asynchronous);
- event loop 是non-blocking網路程式設計的核心, 在現實生活中, non-blocking幾乎是和IO multiplexing(IO複用);
- 為什麼non-blocking網路程式設計中應用層buffer是必需的?
- non-blocking IO的核心思想是避免阻塞在read()或write()或其他IO系統呼叫上;
- IO執行緒只能阻塞在IO multiplexing函式上, 如select/poll/epoll_wait;
- TCP是一個無邊界的位元組流協議;
- 長度為n位元組的訊息分塊到達的可能性有2(n-1)種;
- muduo中的IO都是帶緩衝的IO(buffered IO), 不會自己去read()或write()某個sockect, 只會操作TcpConnection的input buffer和output buffer;
- 在onMessage()回撥裡讀取input buffer;
- 呼叫TcpConnection::send()來間接操作output buffer, 一般不會直接操作output buffer;
一種自動反射訊息型別的Protobuf網路傳輸方案
- 根據type name建立具體型別的Message物件;
- 在muduo中實現protobuf編解碼器與訊息分發器;
- codec的基本功能之一是做TCP分包: 確定每條訊息的長度, 為訊息劃分界限
定時器
- 獲取當前時間, 計算時間間隔;
- 時區轉換與日期計算; 把紐約當地時間轉換為上海當地時間;
- 定時器操作, 比如在預定的時間執行任務, 或者在一段延時之後執行任務;
- Linux時間函式:
- Linux的計時函式, 用於獲得當前時間:
- time/time_t(秒);
- ftime/stuct timeb(毫秒);
- gettimeofday/stuct timeval(微妙);
- clock_gettime/struct timespec(納秒);
- 定時函式:
- sleep;
- alarm;
- usleep;
- nanosleep();
- clock_nanosleep();
- getitimer/setitimer;
- timer_create/timer_settime/timer_gettime/timer_delete;
- timerfd_create/timerfd_gettime/timerfd_settime;
- 計時, 只使用gettimeofday來獲取當前時間;
- clock_gettime精度最高, 但是其系統呼叫的開銷比gettimeofday大;
- gettimeofday在x86平臺上不是系統呼叫, 而是在使用者態實現的, 沒有上下問切換和陷入核心的開銷;
- 一個64位的數可以計數達到30萬年;
- 定時, 只使用timerfd_*系列函式來處理定時任務;
- timerfd_create把時間變成了一個檔案描述符, 該檔案在定時器超時的那一刻變得可讀, 這樣就可以方便地融入select/poll框架中;
- 用統一的方式來處理IO事件和超時事件, 這也正是Reactor模式的長處;
- poll和epoll_wait的定時器精度只有毫秒, 遠低於timerfd_settime的定時精度;
- Linux是一中非實時多工作業系統;
用timing wheel踢掉空閒連線
簡單的訊息廣播服務
- 在分散式中, 除了常用的end-to-end通訊, 還有一對多的廣播通訊;
- tcpdump需要root許可權, 在客戶端和server之間放一箇中繼器(relay);
短址服務
- muduo內建了一個簡陋的http伺服器, 可以處理簡單的HTTP請求;
- 這個HTTP伺服器是面向內網的暴露程式狀態的監控埠, 不是面向公網的功能完善且健壯的httpd, 其介面與J2EE的HttpServlet有幾分類似;
- muduo庫最核心的幾個clsass:
- TcpConnection類;
- TcpServer類;
- TcpClient類;
- Buffer類;
- Channel類 -- 是IO事件回撥的分發器(dispatcher);
- UDNS是一個stub DNS解析器, 它能夠非同步地發起DNS查詢, 再通過回撥函式通知結果;
- c-ares DNS是一款常用的非同步DNS解析庫;
- libcurl是一個常用的HTTP客戶端庫, 可以方便地下載HTTP和HTTPS資料;
- libmicrohttpd -- 可嵌入的HTTP伺服器;
- libpg -- PostgreSQL的客戶端庫;
- libdrizzle -- MySQL的非官方客戶端庫;
- QuickFIX -- 常用的FIX訊息庫;
- 為之提供muduo adapter;
- 對每個TCP連線建立一個lua(一種指令碼語言), muduo為lua提供通訊機制;
- 用lua來編寫業務邏輯, 這樣可以做到線上更改邏輯而不重啟程式;
- skynet開源庫的作者雲風大佬的部落格;