Web 伺服器

星竹z發表於2024-09-29

歡迎訪問我的另一個部落格: https://xingzhu.top/
專案:https://xingzhu.top/archives/webfu-wu-qi-xiao-xiang-mu-linux-c-epoll

HTTP 協議

客戶端 (瀏覽器):

  • 透過瀏覽器位址列給伺服器傳送請求,瀏覽器內部進行資料的封裝
    • 根據 http 協議進行封裝,封裝完畢,資料傳送給伺服器
  • 等待伺服器的回覆
  • 收到伺服器回覆的資料,根據 http 協議解析資料
    • 得到了伺服器回覆的原始資料

伺服器端:

  • 接收資料,被 http 協議封裝過的
  • 根據 http 協議解析資料,得到客戶端請求的原始資料
  • 處理客戶端請求,得到處理結果
  • 給客戶端回覆資料,(資料需要透過 http 協議進行封裝,然後在傳送給客戶端)

http 協議封裝好資料之後是一個資料塊,得到若干行資料,使用的換行符 \r\n

http 請求

http 請求訊息分為四部分:

  • 請求行;不管 get 請求還是 post 請求,請求行是分為三部分
  • 請求頭
  • 空行
  • 客戶端向伺服器提交的資料

get 方式提交資料

  • 如果使用 get 的方式向伺服器提交資料,資料並沒有在請求協議的第四部分,而是在請求行的第二部分
  • 如果使用 get 方式提交資料,第四部分是空的 -> 用於為空
GET /pic/1.jpg HTTP/1.1
Host: 192.168.1.8:6789
Connection: keep-alive    # 一直保持連線
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0(Windows NT 10.0;Win64;x64)
AppleWebKit/537.36(KHTML, like Gecko)
Chrome/80.0.3987.186 Safari/537.36
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,imag
e/webp,image/apng,*/*;q=0.8,application/signed-
exchange;v=b3;q=0.9
Accept-Encoding: gzip,deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
-
  • 14 行為空行
  • get 請求:請求伺服器上的靜態檔案,就是伺服器上存在的檔案
  • /pic/1.jpg 這個是請求的靜態資源,注意這個 / 是伺服器的資源目錄,不是伺服器根目錄,所以需要切換到指定的資源目錄
  • 請求頭是若干個鍵值對,也就是上述從 2 到 8 行,冒號後面跟個空格再寫資料

post 方式提交

POST / HTTP/1.1
Host: 192.168.1.8:6789
Connection: keep-alive
Content-Length: 98         # 提交的內容長度
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: application/x-www-form-urlencoded       # 提交的資料格式 
User-Agent: Mozilla/5.0(Windows NT 10.0;Win64;x64)
AppleWebKit/537.36(KHTML,like Gecko)
Chrome/80.0.3987.106 Safari/537.36
Accept:
text/html,application/xhtml+xml,application/xml;q=8.9,ima
ge/webp,image/apng,*/*;q=0.8,application/signed-
exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

username=subwen%40gq.com&phone=1111111&email=sub%40gq.com
&date=2020-01-01&sex=male&class=1&rule=on
  • 提交的資料是動態的,在伺服器上不存在(如使用者名稱和密碼資訊,是在對應的資料庫上)
  • 提交的資料在位址列中不顯示,但是 get 方式提交會顯示

http 響應

伺服器給客戶端回覆資料,稱之為 http 響應,協議的格式分為四部分:

  • 狀態行
  • 訊息報頭/響應頭
  • 空行
  • 回覆給客戶端的資料

http 響應訊息也是一個資料塊,若干行,換行 \r\n

HTTP/1.1 200 0k
Server: micro_httpd
Date: Fri, 18 Jul 2014 14:34:26 GMT
Content-Type: text/plain;charset=iso-8859-1(必選項)
Content-Length: 32
Location: https://www.biadu.com
Content-Language: zh-CN
Last-Modified: Fri,18 Jul 2014 08:36:36 GMT
Connection: close

#include <stdio.h>
int main()
{
    printf("hello world\n");
    return 0;
}

http 相應狀態碼

狀態程式碼有三位數字組成,第一個數字定義了響應的類別,共分五種:

  • 1xx:指示資訊--表示請求已接收,繼續處理
  • 2xx:成功--表示請求已被成功接收、理解、接受
  • 3xx:重定向--要完成請求必須進行更進一步的操作 (網路地址的重新訪問)
  • 4xx:客戶端錯誤--請求有語法錯誤或請求無法實現
  • 5xx:伺服器端錯誤--伺服器未能實現合法的請求

常見狀態碼:

  • 200 OK 客戶端請求成功
  • 400 Bad Request 客戶端請求有語法錯誤,不能被伺服器所理解
  • 401 Unauthorized 請求未經授權,這個狀態程式碼必須和 WWW-Authenticate 報頭域一起使用
  • 403 Forbidden 伺服器收到請求,但是拒絕提供服務
  • 404 Not Found 請求資源不存在,如:輸入了錯誤的 URL
  • 500 Internal Server Error 伺服器發生不可預期的錯誤
  • 503 Server Unavailable 伺服器當前不能處理客戶端的請求,一段時間後可能恢復正常

詳情查閱: 線上工具 —— OSCHINA.NET社群

相關操作函式

sscanf

// 函式原型
// 將引數 str 的字串根據引數 format 字串來轉換並格式化資料,轉換後
sscanf(const char *str, const char *format)

具體功能如下:

  • 根據格式從字串中提取資料。如從字串中取出整數、浮點數和字串等
  • 取指定長度的字串
  • 取到指定字元為止的字串
  • 取僅包含指定字符集的字串
  • 取到指定字符集為止的字串

可以使用正規表示式進行字串的拆分

正則匹配規則:

  • [1-9]:匹配一個字元,這個字元在 1-9 範圍內就滿足條件
  • [2-7]:匹配一個字元,這個字元在 2-7 範圍內就滿足條件
  • [a-2]:匹配一個字元,這個字元在 a-z 範圍內就滿足條件
  • [A, b, c, D,e,f]:匹配一個字元,這個字元是集合中任意一個就滿足條件
  • [1-9,f-x]:匹配一個字元,這個字元是 1-9,或者 f-x 集合中的任意一個就滿足條件
  • [^1]^ 代表否定,匹配一個字元,這個字元只要不是 1 就滿足條件
  • [^2-8]:匹配一個字元,這個字元只要不在 2-8 範圍內就滿足條件
  • [^a-f]:匹配一個字元,這個字元只要不在 a-f 範圍內就滿足條件
  • [^ ]:匹配一個字元,這個字元只要不是空格就滿足條件
const char *s = "http://www.baidu.com:1234";
char protocol[32] = {0};
char host[128] = {0};
char port[8] = {0};
sscanf(s, "%[^:]://%[^:]:%[1-9]", protocol, host, port);

說明:參考學習 https://subingwen.cn/

相關文章