1. 程式人生 > >HTTP協議(中):請求報文和響應報文

HTTP協議(中):請求報文和響應報文

1. 請求報文格式

1.1 伺服器測試程式碼

伺服器測試程式碼:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>                         
#include <unistd.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>

int main()
{
     // 建立通訊端點:套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0
); if(sockfd < 0) { perror("socket"); return -1; } // 設定本地地址結構體 struct sockaddr_in my_addr; bzero(&my_addr, sizeof(my_addr)); // 清空 my_addr.sin_family = AF_INET; // ipv4 my_addr.sin_port = htons(8000); // 埠 my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // ip
// 繫結 int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr)); if( err_log != 0) { perror("binding"); close(sockfd); return -1; } err_log = listen(sockfd, 10); // 監聽,監聽套接字改為被動 if(err_log != 0) { perror("listen"
); close(sockfd); return -1; } printf("listen client @port=%d...\n", 8000); int connfd; connfd = accept(sockfd, NULL, NULL); // 等待連線 char buf[8*1024] = {0}; read(connfd, buf, sizeof(buf)); printf("%s", buf); while(1) { NULL; } return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

1.2 請求報文格式說明

HTTP 請求報文由請求行、請求頭部、空行、請求包體4個部分組成,如下圖所示: 
這裡寫圖片描述

1)請求行 
請求行由方法欄位、URL 欄位 和HTTP 協議版本欄位 3 個部分組成,他們之間使用空格隔開。常用的 HTTP 請求方法有 GET、POST。

GET:

  • 當客戶端要從伺服器中讀取某個資源時,使用GET 方法。GET 方法要求伺服器將URL 定位的資源放在響應報文的資料部分,回送給客戶端,即向伺服器請求某個資源。
  • 使用GET方法時,請求引數和對應的值附加在 URL 後面,利用一個問號(“?”)代表URL 的結尾與請求引數的開始,傳遞引數長度受限制,因此GET方法不適合用於上傳資料。
  • 通過GET方法來獲取網頁時,引數會顯示在瀏覽器位址列上,因此保密性很差。
GET / HTTP/1.1
Host: 192.168.48.98:8000
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

POST:

  • 當客戶端給伺服器提供資訊較多時可以使用POST 方法,POST 方法向伺服器提交資料,比如完成表單資料的提交,將資料提交給伺服器處理。
  • GET 一般用於獲取/查詢資源資訊,POST 會附帶使用者資料,一般用於更新資源資訊。POST 方法將請求引數封裝在HTTP 請求資料中,而且長度沒有限制,因為POST攜帶的資料,在HTTP的請求正文中,以名稱/值的形式出現,可以傳輸大量資料。
POST /search HTTP/1.1  
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,application/msword, application/x-silverlight, application/x-shockwave-flash, */*  
Referer: <a href="http://www.google.cn/">http://www.google.cn/</a>  
Accept-Language: zh-cn  
Accept-Encoding: gzip, deflate  
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)  
Host: <a href="http://www.google.cn">www.google.cn</a>  
Connection: Keep-Alive  
Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-FxlRugatx63JLv7CWMD6UB_O_r  

hl=zh-CN&source=hp&q=domety 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2)請求頭部 
請求頭部為請求報文添加了一些附加資訊,由“名/值”對組成,每行一對,名和值之間使用冒號分隔。

請求頭部通知伺服器有關於客戶端請求的資訊,典型的請求頭有:

請求頭 含義
User-Agent 請求的瀏覽器型別
Accept 客戶端可識別的響應內容型別列表,星號“ * ”用於按範圍將型別分組,用“ / ”指示可接受全部型別,用“ type/* ”指示可接受 type 型別的所有子型別
Accept-Language 客戶端可接受的自然語言
Accept-Encoding 客戶端可接受的編碼壓縮格式
Accept-Charset 可接受的應答的字符集
Host 請求的主機名,允許多個域名同處一個IP 地址,即虛擬主機
connection 連線方式(close或keepalive)
Cookie 儲存於客戶端擴充套件欄位,向同一域名的服務端傳送屬於該域的cookie

3)空行 
最後一個請求頭之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有請求頭。

4)請求包體 
請求包體不在GET方法中使用,而是POST方法中使用。 
POST方法適用於需要客戶填寫表單的場合。與請求包體相關的最常使用的是包體型別Content-Type和包體長度Content-Length。

2. 響應報文格式

2.1 客戶端測試程式碼

編寫客戶端程式:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>                         
#include <unistd.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>

int main()
{
     // 建立通訊端點:套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);  

    // 設定伺服器地址結構體  
    struct sockaddr_in server_addr;  
    bzero(&server_addr,sizeof(server_addr)); // 初始化伺服器地址  
    server_addr.sin_family = AF_INET;   // IPv4  
    server_addr.sin_port = htons(8000); // nginx伺服器監聽的埠 
    inet_pton(AF_INET, "192.168.48.98", &server_addr.sin_addr);   // 伺服器ip  

     // 主動連線伺服器  
    int err_log = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));  
    if(err_log != 0)  
    {  
        perror("connect");  
        close(sockfd);  
        return -1;  
    }

    //http請求報文包
    char send_buf[] = 
        "GET /mike.html HTTP/1.1\r\n"
        "Accept: image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*\r\n"
        "Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3\r\n"
        "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)\r\n"
        "Accept-Encoding: gzip, deflate\r\n"
        "Host: 192.168.48.98:8000\r\n"
        "Connection: Keep-Alive\r\n"
        "\r\n";

    //傳送http請求報文包
    send(sockfd, send_buf, sizeof(send_buf)-1, 0);

    //獲取http響應報文
    char recv_buf[8*1024] = {0};
    recv(sockfd, recv_buf, sizeof(recv_buf), 0);
    printf("%s", recv_buf);

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

2.2 響應報文格式說明

HTTP 響應報文由狀態行、響應頭部、空行、響應包體4個部分組成,如下圖所示: 
這裡寫圖片描述

1)狀態行 
狀態行由 HTTP 協議版本欄位、狀態碼和狀態碼的描述文字3個部分組成,他們之間使用空格隔開。

狀態碼: 
狀態碼由三位數字組成,第一位數字表示響應的型別,常用的狀態碼有五大類如下所示:

狀態碼 含義
1xx 表示伺服器已接收了客戶端請求,客戶端可繼續傳送請求
2xx 表示伺服器已成功接收到請求並進行處理
3xx 表示伺服器要求客戶端重定向
4xx 表示客戶端的請求有非法內容
5xx 表示伺服器未能正常處理客戶端的請求而出現意外錯誤

常見的狀態碼舉例:

狀態碼 含義
200 OK 客戶端請求成功
400 Bad Request 請求報文有語法錯誤
401 Unauthorized 未授權
403 Forbidden 伺服器拒絕服務
404 Not Found 請求的資源不存在
500 Internal Server Error 伺服器內部錯誤
503 Server Unavailable 伺服器臨時不能處理客戶端請求(稍後可能可以)



2)響應頭部 
響應頭可能包括:

響應頭 含義
Location Location響應報頭域用於重定向接受者到一個新的位置
Server Server 響應報頭域包含了伺服器用來處理請求的軟體資訊及其版本
Vary 指示不可快取的請求頭列表
Connection 連線方式

3)空行 
最後一個響應頭部之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有響應頭部。

4)響應包體 
伺服器返回給客戶端的文字資訊。