親手打造 HTTP 網路服務:超小 Web Server 的撰寫
今天一時心血來潮下,前後花了 30 分鐘,動手寫了一個 Web Server,這是個僅僅使用 170 行﹝若是移除空行和註解也許只有 100 行不到﹞左右 C 語言程式所寫的『超小』Web Server,只有支援 GET 命令,沒有 CGI 、虛擬目錄的其他功能。 以下是瀏覽器對伺服器一個單純的 HTTP 通訊: GET /index.html HTTP/1.0<CF><LF> <CF><LF> HTTP 協定中,標準網路通訊 Port 是 80,瀏覽器使用『GET /index.html HTTP/1.0』命令來指定抓取網站根目錄的 index.html 檔案,每行指令以換行字元『\r\n』結尾,最後再一次的『\r\n』代表等待伺服器回傳資料。就這段非常單純的通訊內容而言,我寫的 Web Server,最少要能夠解析這行命令。 撰寫 Web Server 比較需要的程式技術,大概就是 Daemon、多執行緒、網路連線操作。 關於背景服務的 Daemon 程式寫法,我在另一篇筆記上有簡單記錄,應該不是什麼大問題。 而多執行緒的使用,是為了提供多使用者同時連線,我們需要同時處理眾多用戶端的連線要求,而不是等一個用戶處理完再接受下一個人連線。但是,為了不使用太複雜的多執行緒系統機制,在這程式中我改用 fork() 多行程的方式撰寫,這樣不但簡化了程式,也剛剛好讓我的 Web Server 可以在許多嵌入式系統中執行,因為多數微型的嵌入式系統,並沒有支援多執行緒。 最後一個會用到的程式技術是網路連線操作,會和寫用戶端網路程式有極大不同,因為要監聽網路卡上的 Port,等到有用戶端連線時再進行處理。其中依照流程會呼叫下面四個函式: socket() /* 開啟網路 Socket */ bind() /* 開啟網路監聽器 */ listen() /* 開始監聽網路 */ accept() /* 等待客戶端連線 */ 這 Web Server 將會使用 /tmp 當根目錄,每次有使用者連線,就會 fork() 出一個子行程去處理用戶端的要求。主要由 main() 啟動和初始化網路監聽、fork(),然後交由自訂的 handle_socket() 去解析命令和回傳資料。 Web Server 原始碼: #include...