http伺服器究竟做了什麼 四

2021-08-19 06:32:56 字數 1677 閱讀 7487

這篇開始講伺服器的**.為了讓初學者更好的理解http伺服器的基本原理,抓住主幹,排除其他干擾,我這裡用了最輕量級的http伺服器tinyhttp,總共**只有500行左右.麻雀雖小,五臟俱全. tinyhttp實現了http伺服器的基本功能.

首先,初學者要懂基本的socket程式設計,知道socket程式設計的基本流程.因為http伺服器也是基於socket程式設計的.

為了更直白的演示http伺服器的流程,tinyhttp沒有採用複雜的網路模型,而是採用最基本的多執行緒來處理新的連線.即沒有乙個新的socke連線都開啟乙個新的執行緒.

當收到瀏覽器請求之後,解析請求頭,根據是否為get,post進行相應的處理.http協議頭都是文字協議,而且每個欄位都以\r\n來分隔,所以我們可以封裝乙個函式get_line,專門解析一行的資料.

有個問題就是,由於各個系統的分隔符不一致,比例windows是\r\n,linux為\n,mac又是\r,所以這裡要特別的處理一下,以適應各種不同的系統.這裡有個處理技巧,當遇到\r的時候,怎麼知道是一行的結束了,還是後面會有\n?可以用msg_peek引數,窺看一眼後面的資料,如果後面的乙個字元不是是\n,說明這一行已經結束,否則就要再讀\n來結束這一行.

有了上面的get_line函式,我們解析出瀏覽器請求的方式.我畫了get_line的大致流程圖,如下:

可以看到,如果只是單純的請求檔案,那麼只需要server_file,讀取並傳送檔案內容即可.如果是post或者帶引數的get,則要執行cgi程式.

這裡我們重點講一下伺服器是如何與cgi程式互動的.

我們知道,cgi程式實際上也是乙個使用者程序.

伺服器以子程序的方式來啟動他,這樣他們就可以共享環境變數,程序間的通訊也變的簡單很多.

基本的環境變數有區分get或post的request_method,對於get,肯定有query_string,而post必定會有content_length,由於以子程序的方式開啟,這些環境變數都會進入到cgi程式的環境變數中.

對於get方式,沒什麼好說的,cgi程式獲取環境變數的值就行,而對於post方式要複雜一點.環境變數中只有content_length,獲取到他的值之後,還要讀取socket,才能獲取post真正的資料.

問題來了,伺服器讀取content_length長度的資料之後,怎麼把這個資料傳給cgi程式?然後cgi程式又是怎麼把處理結果返回給伺服器的呢,不管是get還是post肯定都需要傳回資料的,否則瀏覽器展現什麼呢.

這裡不能再次利用環境變數了,因為環境變數只適合共享那些比較小的資料,像網頁頁面資料那麼大肯定是不適合這種方式的.父程序和子程序還有另外一種易操作的通訊方式--匿名管道.可以參考匿名管道為什麼可以在父子程序間通訊.

我們建立兩個管道input,output.伺服器獲取post體的資料之後寫入input管道的一端(input[1]),cgi程式就可以從input的另一端input[0]獲取post體資料了.奇怪的是cgi程式是如何獲取管道的另一端的呢?這裡利用了乙個很巧妙的方式--重定向,利用dup2將input[0]重定向為cgi程式的輸入檔案描述符.

cgi程式執行業務邏輯之後,給伺服器返回資料則通過output管道.同理將管道的一邊output[1]重定向為cgi程式的輸出檔案描述符.只要cgi程式向標準輸出寫入,那麼管道的另一邊,伺服器的output[0]就能收到資料,進而傳送給瀏覽器.

HTTP協議學習(四) Web伺服器

本篇疑惑 http伺服器如何處理http請求的?首先介紹一下什麼是web伺服器,我個人理解就是能支撐web應用正常工作的軟硬體結合的乙個玩意兒。web伺服器可以是一套軟體,一台小型機等。但最終提供支援的都是軟體。硬體只是作為乙個載體用於支撐web伺服器軟體的執行。接收客戶端請求 接收請求 處理請求 ...

搭建http伺服器

本節以中標麒麟桌面作業系統 龍芯版 為例,簡單介紹 http伺服器搭建方法,其他作業系統或搭建 ftp 伺服器,請參考相關使用者手冊或網路資料。1.在 var www html 下建立update,再在update下建立packages 和repodata。將軟體包拷貝到 var www html ...

搭理http伺服器

由於在某些特定場景下,我們的外網訪問會受到限制,如果有一些訪問需求的話就需要乙個 作為中轉了。首先需要一台機器作為中轉的伺服器,這時候當然要去阿里雲買一台啦微笑。作業系統一定要選linux,我使用的是centos。之後的主要目標是在這台機器上搭建乙個http 了。當然肯定不可能自己從頭開始寫,用現有...