# C++ HTTP 伺服器開發 Server Dev Log ![](https://hackmd.io/_uploads/Sy_kkiSkC.jpg) > [What makes something "Kafkaesque"? - Noah Tavlin - YouTube](https://www.youtube.com/watch?v=wkPR4Rcf4ww) ### 前言 電腦就像是一個卡夫卡式 (kafkaesque) 的微型社會縮影 -- 黑盒子裡關著的是數千個畢其一生 (PC 燒掉前) 都在為這個世界巨輪正常轉動而努力無盡工作的精靈: :::info 有負責管理 Socket 接口的精靈;有專責打包包裹的精靈;有驅動精靈分別將包裹運上飛機、貨船和鴿子。同時 NET_RX_SOFTIRQ 精靈正注意關口有無新進貨物,如果觀察到新到港貨物隨即致電 IRQ 訊息給一個名叫 PIC 的處理器秘書精靈,並在此時偷懶正著被抓到 (IRQF_DISABLED),卻只能眼看港口堆滿待簽收的貨物而無法動作,甚至有些封包已經被 drop 到海裡了,ICMP 封包一去不返,被鄰近的航空哨站記了一記警告。 ::: ![](https://hackmd.io/_uploads/HkNcjJ1zT.png) > OS 裡網路運作邏輯 (Operating System Design & Implementations) 在計算機網路課程後的好奇心驅使下,越是深入在網路上挖掘資料,越是對網路千變萬化、無邊無際的應用感到新奇:從 SSL 的 CA 運作原理,到 Bob and Alice,再到行動網路從 1G 演變到 5G,或安全議題如 2G 沒有驗證基地台來源的機制造成類似 HTTP 中間人調包攻擊等。獲得這些額外的網路知識,完全打開以前對網際網路極狹隘的想像,原來網路是如此龐大的領域,又可結合很多適合的領域如: 分散式網路、物聯網、物理學機器應用、生物社會學研究 (蜜蜂、螞蟻、魚群...)、地理極端環境應用 (海洋、地層、太空)、資本經濟機制改良 (區塊鏈是一種嘗試)、AI 計算甚至是研究社會心理學等等,隨便都是一個有趣又涉略極廣的項目,遂打算自己利用閒暇時間利用 C++ 從零開發 HTTP 伺服器。 ### HTTP 200 OK ![](https://hackmd.io/_uploads/BkmPVbJMT.png) > 從瀏覽器發起的 GET 請求示意圖 透過觀察自建的 C++ 伺服器和瀏覽器間的封包互動,近距離體會到「網路協議」是如何在應用程式背後實現溝通交流的。經過自己訂定 HTTP 的標頭規則像是 Content-Type、Etag、Cookies;把檔案拆成一包包的 Chunk 塞進 TCP/IP 的 Buffer 送出。那時才恍然大悟,原來網際網路的在 TCP/IP 基礎上實現 HTTP 應用層就是這樣實現的啊。 至此,HTTP 不再只是每次輸入 URL 時必打的前綴詞,在我眼中已經變成一個個和瀏覽器交互的過程,感觸之深至今都難以忘懷。 ### 網路 WebSocket 層 那時伺服器漸漸有了 HTTP 伺服器雛型,伺服器已能處理 GET、POST 等等請求回應。伺服器無法主動向客戶推送訊息,於是讓我開始納悶其他網站是如何實現即時訊息、影音串流功能的,好奇他們是如何做到實時的雙向溝通。心想,總不可能是瀏覽器一直 polling request 跟伺服器要回應吧! 於是藉此機會研究了 HTTP 上即時雙向溝通的辦法,我又認識到瀏覽器上 Web API 支援的許多有趣功能,如: Streaming、WebSocket、WebRTC 等。 尤其是 WebSocket,主流瀏覽器和伺服器都支持的基礎功能,就是在 HTTP 基礎之上以長連線方式連接達到即時訊息互動的效果。所以我參考了 WebSocket 的定義,用 C++ 手刻出一個 WebSocket 連線的處理程式,包括: 握手程序、send 和 recieve 函數。並將此程式打包成專案中實用的函式庫。 同一時間我在「[衛星計畫專案](/ByZv1wfWp#團隊專案-IRIS-衛星計畫)」中做衛星封包處理,對 header、control bit 和 payload 的概念不那麼陌生,加上原本修課時就看過 IPv4 和 ICMP 封包的長相,所以在閱讀和實作 WebSocket 協定時就沒那麼費勁。 ![](https://hackmd.io/_uploads/Hyt8JU2ba.png) > 測試 WebSocket 程式 ### 其他實作 之後的時間,為了因應一些應用上的需求,我嘗試實作: - 為了方便管控聊天室的成員和發話權限設計了 WebSocket 的對使用者廣播模組。 - 為了有效利用和保護連線資源改用 Thread Pool 管理連線工作分派事宜。 - 為了將這個伺服器也作 LINE 機器人回覆角色,參考 LINE 機器人文件定義後也設計 LINE 封包處理程序。 - 為了驗證來自 LINE 伺服器的訊息簽章實作了 SHA2 (SHA-256) 的 HMAC 函數和 base64 的編解碼處理函數。 - 為了有自己的資料庫系統來儲存資料,配合修 DBMS 的課自己實作了一個簡單概念的資料庫系統和相應的實用函式庫供伺服器開發使用。 ### 後記 回過頭來看雖專案並不預期完美,可以改進的地方譬如有引入 OOP、Design Pattern 和 try catch 使用等。但我在這時間學會自己找解決方法、找學習資源,逐漸有了獨立學習和開發研究的能力。並在之後開始一系列的前後端開發旅程。 :arrow_right: 更多網頁全端開發細節: [Web App Development - shibarashinu](/eaYYQHxLRb6DjRlg27xhEg)