微型個人博客服務器

Http相關簡介

Http是應用層的基於請求響應的一個協議, 其中Http的請求響應可以分爲四部分. 請求行, 請求報頭,空行, 請求正文.其中請求行包括了請求方法, url, 版本號, 請求報頭包括請求屬性, 冒分割的鍵值對, 每組屬性之間都以換行的形式分開, 最後一空行作爲請求的結束標識. 最後一部分是請求正文.當請求正文存在的時候, 會在頭部信息中有一個Content_Length的屬性標識正文段的長度.
Http響應也包括四部分, 響應行, 響應報頭, 空行, 響應正文, 其中響應行包括版本號, 狀態編號, 狀態描述, 響應正文也是以key:value的形式存在, 其中每一個響應屬性之間以換行爲結束表示, 第三部分爲空行, 最後一部分爲響應正文, 其中當響應正文存在的時候, 響應報頭中會存在一個Content_Length用來表示響應正文的長度

網絡中數據的傳輸

客戶端發在瀏覽其中輸入一個url此時會經過以下幾個步驟
1.客戶端在瀏覽器輸入一個url
2.瀏覽器查詢當前瀏覽器的緩存, 系統緩存, 路有緩存, 如果緩存中有用戶輸入的url就直接將內容顯示給用戶, 如果沒有繼續查找
3.系統查找系統緩存, 查看是否有域名IP地址,如果有, 則繼續查找, 如果沒有, 繼續查看找
4.路由器查找路由緩存, 如果有對應的IP地址則返回, 否則繼續查找
5.本地域名服務器採用迭代的方式進行查詢, 先向根域名服務器進行查詢
6.根域名服務器告訴本地域名服務器下一次應該訪問的服務器的IP地址,
7.本地域名服務器拿着這個IP地址到頂級域名服務器訪問對應的資源,
8.頂級域名服務器此時告訴本地域名服務器下一次應該查詢的權限域名服務器的IP地址
9.本地域名服務器此時會向權限域名服務器進行訪問查詢
10.權限域名服務器告訴本地域名服務器所要查詢的資源對應的主機的IP地址
11.此時本地域名服務器查詢到資源後將自己查詢到的IP地址告訴給主機
12.主機瀏覽器獲取到Web服務器的IP地址後,與服務器建立TCP連接
13.此時瀏覽器所在的客戶機 通過這個IP地址給對應的服務器發送一個請求連接的報文
14.服務器接收到主機發來的請求後向客戶機發出對應的應答報文,同時也給客戶機發送一個請求連接報文
15.客戶機接收到這個請求後給服務器發送一個確認報文
16.此時客戶機和瀏覽器之間建立了連接完成, 開始通信
17.瀏覽器發出對應的文件請求
18.服務器對瀏覽器發出的文件請求進行響應, 將用戶想要訪問的信息發送給瀏覽器
19.瀏覽器釋放連接, 向服務器發送一個FIN 報文
20.服務器接收到這個FIN報文的時候給對應的客戶機發送一個ACK報文表名自己同意釋放鏈接, 同時服務器會給用戶發送一個FIN報文, 表名自己請求釋放連接
21.客戶機接收到FIN報文後給服務器發送一個ACK報文, 表名自己受到FIN報文,
22.連接釋放, 雙方停止發送數據

Http的特點

簡單快速, 服務器的規模小, 通信速度很快
Http允許傳輸任意類型的數據對象, 傳輸的類型由Content_type標記
無連接, 每次連接只處理一個請求, 處理完請求後就進行關閉
協議本身不會保存用戶請求和響應

URL & URI & URN

URI是一個統一資源標識符, 它只是一個資源的標示
URL 是一個更加具體的URI, 可以通過URL定位到該資源存放在哪裏, 並且可以得知如何獲取到該資源.每個網頁都對應一個URL地址(俗稱網址),具有全球唯一性。它包含的信息指出文件的位置以及瀏覽器應該怎麼處理它。 一個完整的URL包括協議類型、主機類型、路徑和文件名
URN 通過名字標識一個資源

Http請求方法

GET方法
如果瀏覽器訪問資源的方法是GET方法, 此時就會將用戶請求的關鍵字拼接到URL後面, 同時GET方法可能帶參數也可能不帶參數
POST方法
POST方法不會將用戶提交上去的數據放到url中, 它會將用戶提交上去的數據放到正文中

CGI

瀏覽器除了從服務器上獲取一些資源之外, 有時還需要向服務器上提交一些數據, 爲了實現網頁的交互性, 此時就需要以CGI機制來運行
當用戶訪問的資源具有可執行的時候, 此時程序就要以CGI的形式進行運行, 其中CGI的運行有兩種可能, 一種是當請求的方法是POST, 另外一種就是當請求的資源是GET, 並且在URL中帶了參數, 此時的運行方式即就是CGI運行方式

Http響應狀態碼及其描述

2XX成功

200: 請求訪問被正確處理
204: 請求結果被正確處理, 但是響應信息沒有響應正文
206: 客戶端對服務器進行了範圍請求, 服務器成功執行了GET 請求, 響應報文包含了Content-Range指定的實體內容範圍

3XX成功

瀏覽器爲了正確出處理請求需要執行一些特殊的處理動作
301永久性重定向:資源被重新分配了新的url, 要想訪問該資源就得以新的url去訪問資源
302臨時性重定向: 目標資源暫時被分配了新的url,需要訪問就得以新的url進行訪問

4XX客戶端錯誤

400 請求錯誤:表示請求報文中存在語法錯誤, 服務器無法解析該請求, 需要修改請求內容, 重新發送.
403 瀏覽器訪問的資源被服務器拒絕. 服務器沒有必要給出詳細的理由
404 請求的資源不存在

5XX服務器錯誤

500 服務器端在執行的時候發生了錯誤
503 服務器處於超載狀態, 目前正在維護, 無法請求處理.

MySlq相關接口

mysql_get_client_info()//引入對應的MySql庫
MySql* mysql_init(MySql* mysql);//初始化
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
 const char *user,
 const char *passwd,
 const char* db,
 unsigned int port,
 const char* unix_socket,
 unsigned long clientflag);//連接數據庫
 int mysql_query(MYSQL* mysql, const char* q);//下發MySql命令
 MYSQL_RES *mysql_store_result(MYSQL* mysql);//讀取結果
 unsigned int mysql_num_fields(MYSQL_RES *res);//獲取列數
 MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);//獲取列名
 void mysql_close(MYSQL* sock);//關閉MySql連接

項目分析

1.用戶在瀏覽器上輸入一個url
2.服務器將用戶的請求進行分析, 向用戶發出Http響應, 最終將用戶請求的資源以一個html頁面展示給用戶
3.當用戶請求的資源是一個可執行程序的時候, 此時就會進行簡單的cgi運行, 最終將運行的結果展示給用戶
4.當用戶輸入數據, 服務器將對應的數據插入到數據庫中
5.服務器將對應的數據庫的信息以html頁面的格式展示給用戶

項目實現思路

1.創建套接字
2.將對應的請求處理(將所有的換行都轉換爲反斜槓n)
3.對讀取到的請求報文進行分析, 提取對應的方法, 判斷該方法是GET 方法還是POST方法
4.如果是GET方法, 就直接判斷資源請求的資源是否存在, 資源如果存在, 就將該資源返回給用戶, 如果該資源不存在, 就返回404頁面, 如果請求的資源是一個目錄就將返回一個首頁給瀏覽器
5.如果是POST方法, 就以cgi機制運行, 同時將正文的長度獲取, 以進行參數獲取

項目中的CGI運行機制

首先判斷方法是GET 還是POST, 如果是GET方法, 那麼此時的參數已經獲取到(通過url放到了對應的query_string 中)此時就將請求行請求正文全部讀完, 如果是POST方法, 此時就需要讀取請求報頭獲得Content_length, 通過Content_length獲取參數.然後將發送響應行首信息.此時就會出現一個問題, 既然是CGI機制, 那麼就需要在一個集成中取執行另一個可執行程序, 此時就需要創建一個子進程, 但是子進程和父進程之間是獨立的, 父進程想要拿到子進程的運行結果就必須將兩個進程之間進行關聯, 此時就需要引入管道實現進程間通信.
子進程需要執行另外一個可執行程序的話就需要程序替換, 程序替換回將當前的數據和代碼全部替換, 此時如果將其替換掉, 子進程還怎麼拿到對應的數據, 這個時候就引入了環境變量, 爲了讀寫方便, 將管道直接重定向到對應的0和1中, 此時父進程只需要將子進程的執行結果拿到之後將其交給瀏覽器即可, 子進程只需要從父進程那裏將數據拿到即可
總結一下:
父進程:
創建兩個管道, 關閉相應的文件描述符
POST:繼續讀取數據, 直到讀完POST的參數部分
GET直接從子進程那裏讀取結果
將數據和方法全部交給子進程等待子進程結果
子進程:
關閉相應的文件描述符
重定向標準輸入標準輸出
通過環境變量傳去參數
進程程序替換

錯誤處理

將對應的請求處理完之後, 發出對應的響應, 然後在正文中將404頁面發出去

部分圖片展示

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章