今天小编给大家分享一下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...
", 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;
}浏览器输入url地址: 
终端启动服务器程序,测试http的请求报文: 
1.2 请求报文格式说明
HTTP 请求报文由请求行、请求头部、空行、请求包体4个部分组成,如下图所示: 
1)请求行 
 请求行由方法字段、URL 字段 和HTTP 协议版本字段 3 个部分组成,他们之间使用空格隔开。常用的 HTTP 请求方法有 GET、POST。
GET:
当客户端要从服务器中读取某个资源时,使用GET 方法。GET 方法要求服务器将URL 定位的资源放在响应报文的数据部分,回送给客户端,即向服务器请求某个资源。
使用GET方法时,请求参数和对应的值附加在 URL 后面,利用一个问号(“?”)代表URL 的结尾与请求参数的开始,传递参数长度受限制,因此GET方法不适合用于上传数据。
通过GET方法来获取网页时,参数会显示在浏览器地址栏上,因此保密性很差。
GET / Host: 192.168.11.80:9889 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
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="https://www.maopiaopiao.com">
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 客户端测试代码
启动nginx服务器: 
编写客户端程序:
#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(80); // nginx服务器监听的端口 
    inet_pton(AF_INET, "192.168.31.109", &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
"
        "Accept: image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*
"
        "Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3
"
        "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)
"
        "Accept-Encoding: gzip, deflate
"
        "Host: 192.168.31.109:8000
"
        "Connection: Keep-Alive
"
        "
";
    //发送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;
}在浏览器中输入url地址,得到test.html网页: 
启动程序,测试http的成功响应报文: 
在浏览器中输入url地址,没有得到相应网页: 
启动程序,测试http的失败响应报文: 
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)响应包体 
 服务器返回给客户端的文本信息。