【Linux网络编程】第十一弹---HTTP协议全解析:从请求响应到方法与Header的详尽指南

个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】【Linux网络编程】

目录

1、HTTP 协议

1.1、认识 URL

​1.2、urlencode 和 urldecode

1.3、HTTP 协议请求与响应格式

1.3.1、代码修改 

1.3.2、Http.hpp

1.3.3、ServerMain.cc

1.3.4、腾讯云配置安全组(防火墙)

1.3.5、在浏览器中访问

1.3.5、修改Http.hpp中执行方法

1.3.6、HTTP 请求

1.3.7、HTTP 响应 

1.3.8、基本的应答格式

1.4、HTTP 的方法 

1.4.1、HTTP 常见方法

1.5、HTTP 常见 Header

1.5.1、关于 connection 报头


1、HTTP 协议

虽然我们说, 应用层协议是我们程序猿自己定的. 但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)就是其中之一。

在互联网世界中,HTTP(HyperText Transfer Protocol,超文本传输协议)是一个至关重要的协议。它定义了客户端(如浏览器)与服务器之间如何通信,以交换或传输超文本(如 HTML 文档)。

HTTP 协议是客户端与服务器之间通信的基础。客户端通过 HTTP 协议向服务器发送请求,服务器收到请求后处理并返回响应。HTTP 协议是一个无连接、无状态的协议,即每次请求都需要建立新的连接,且服务器不会保存客户端的状态信息

1.1、认识 URL

平时我们俗称的 "网址" 其实就是说的 URL

初步认识

深刻认识 

1.2、urlencode 和 urldecode

/ ? : 等这样的字符, 已经被 url 当做特殊意义理解了. 因此这些字符不能随意出现.比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.
转义的规则如下:
将需要转码的字符转为 16 进制,然后从右到左,取 4 位(不足 4 位直接处理),每 2 位做一位,前面加上%,编码成%XY 格式!

例如: 

使用特殊字符访问浏览器时,会进行编码(urlencode)与解码(urldecode)的过程! 

1.3、HTTP 协议请求与响应格式

编写代码见见http 请求与应答

拷贝上一弹的网络计算器的部分代码(InetAddr.hpp,LockGuard.hpp,Log.hpp,Makefile,ServerMain.cc,Socket.hpp,TcpServer.hpp),并适当修改代码进行测试!

1.3.1、代码修改 

修改TcpServer.hpp文件中的执行方法声明:

using service_t = std::function<std::string (std::string &requeststr)>;

TcpServer类的成员变量与构造函数同理!

class TcpServer
{
public:
    TcpServer(service_t service,uint16_t port = gport)
        :_port(port),
        _listensock(std::make_shared<TcpSocket>()),
        _isrunning(false),
        _service(service)
    {
        _listensock->BuildListenSocket(_port);
    }
private:
    uint16_t _port;
    SockSPtr _listensock;
    bool _isrunning;
    service_t _service; // // 执行方法
};

Execute()函数也需修改!

// 无法调用类内成员 无法看到sockfd
static void *Execute(void *args)
{
    ThreadData *td = static_cast<ThreadData *>(args);
    pthread_detach(pthread_self()); // 分离新线程,无需主线程回收
    
    std::string requeststr;
    // 后面不做请求的分离,我们认为读到的是一个完整的请求 -bug
    ssize_t n = td->_sockfd->Recv(&requeststr);
    if(n > 0)
    {
        std::string responsestr = td->_self->_service(requeststr); // 执行回调
        td->_sockfd->Send(responsestr);
    }
    
    td->_sockfd->Close();
    delete td;
    return nullptr;
}

1.3.2、Http.hpp

该类用于处理服务的回调函数

#pragma once

#include <iostream>
#include <string>

class HttpServer
{
public:
    HttpServer()
    {}
    std::string HandlerHttpRequest(std::string &req)
    {
        std::cout << "---------------------------------------------" << std::endl;
        std::cout << req;

        return std::string();
    }
    ~HttpServer()
    {}
};

注意: 此处的执行方法返回的是空串,后序再进行修改!

1.3.3、ServerMain.cc

ServerMain.cc文件创建TcpServer智能指针对象!

#include "TcpServer.hpp" // 会话层
#include "Http.hpp"

// ./calserver 8888
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        std::cerr << "Usage: " << argv[0] << "local-port" << std::endl;
        exit(0);
    }

    uint16_t port = std::stoi(argv[1]);

    HttpServer hserver;

    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>(
        std::bind(&HttpServer::HandlerHttpRequest, &hserver, std::placeholders::_1),
        port);
    tsvr->Loop();

    return 0;
}

1.3.4、腾讯云配置安全组(防火墙)

云服务器只有配置了安全组(防火墙)才能直接使用IP + 端口号在浏览器访问!

步骤一:执行服务端程序:

步骤二:安装telnet服务

步骤三:判断是否配置了安全组:

在cmd中执行命令 telnet ip port    !

出现上面的情况表示没有配置安全组!

步骤四:配置安全组(防火墙):

在腾讯云官网的服务器中配置!

 步骤五:再次判断是否配置了安全组

在cmd中执行命令 telnet ip port    !

此时表示配置成功!

1.3.5、在浏览器中访问

在浏览器中访问的前提是将服务端启动起来,在浏览器输入公网IP:端口号

1.3.5、修改Http.hpp中执行方法

执行方法中给客户端发送一些信息!

std::string HandlerHttpRequest(std::string &reqstr)
{
    std::cout << "---------------------------------------------" << std::endl;
    std::cout << reqstr;

    // return std::string();
    std::string responsestr = "HTTP/1.1 200 OK\r\n";
    responsestr += "Content-Type: test/html\r\n";
    responsestr += "\r\n";
    responsestr += "<html><h1>hello linux,hello net!<h2></html>";

    return responsestr;
}

错误示范(X) 

此处是因为方法中的代码错了一个英文,导致没有打印出来东西,而是下载内容!

正确示范(√)

修改HandlerHttpRequest()函数中的一个英文字母即可!

1.3.6、HTTP 请求

  • 首行: [方法] + [url] + [版本]
  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\r\n 分隔;遇到空行表示 Header 部分结束
  • Body: 空行后面的内容都是 Body. Body 允许为空字符串. 如果 Body 存在, 则在Header 中会有一个 Content-Length 属性来标识 Body 的长度;

1.3.7、HTTP 响应 

  • 首行: [版本号] + [状态码] + [状态码解释]
  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\r\n 分隔;遇到空行表示 Header 部分结束
  • Body: 空行后面的内容都是 Body. Body 允许为空字符串. 如果 Body 存在, 则在Header 中会有一个 Content-Length 属性来标识 Body 的长度; 如果服务器返回了一个 html 页面, 那么 html 页面内容就是在 body 中.

1.3.8、基本的应答格式

1.4、HTTP 的方法 

其中最常用的就是 GET 方法和 POST 方法. 

1.4.1、HTTP 常见方法

1. GET 方法(重点)
用途:用于请求 URL 指定的资源
示例:GET /index.html HTTP/1.1
特性:指定资源经服务器端解析后返回响应内容。

form表单

2. POST 方法(重点)
用途:用于传输实体的主体,通常用于提交表单数据。
示例:POST /submit.cgi HTTP/1.1
特性:可以发送大量的数据给服务器,并且数据包含在请求体中。

3. PUT 方法(不常用)
用途:用于传输文件,将请求报文主体中的文件保存到请求 URL 指定的位置。
示例:PUT /example.html HTTP/1.1
特性:不太常用,但在某些情况下,如 RESTful API 中,用于更新资源。
4. HEAD 方法
用途:与 GET 方法类似,但不返回报文主体部分,仅返回响应头。
示例:HEAD /index.html HTTP/1.1
特性:用于确认 URL 的有效性及资源更新的日期时间等。

5. DELETE 方法(不常用)
用途:用于删除文件,是 PUT 的相反方法。
示例:DELETE /example.html HTTP/1.1
特性:按请求 URL 删除指定的资源。
6. OPTIONS 方法
用途:用于查询针对请求 URL 指定的资源支持的方法。
示例:OPTIONS * HTTP/1.1
特性:返回允许的方法,如 GET、POST 等。

1.5、HTTP 常见 Header

  • Content-Type: 数据类型(text/html 等)
  • Content-Length: Body 的长度
  • Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
  • User-Agent: 声明用户的操作系统和浏览器版本信息;
  • referer: 当前页面是从哪个页面跳转过来的;
  • Location: 搭配 3xx 状态码使用, 告诉客户端接下来要去哪里访问;
  • Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;

1.5.1、关于 connection 报头

HTTP 中的 Connection 字段是 HTTP 报文头的一部分,它主要用于控制和管理客户端与服务器之间的连接状态。

核心作用

  • 管理持久连接:Connection 字段还用于管理持久连接(也称为长连接)。持久连接允许客户端和服务器在请求/响应完成后不立即关闭 TCP 连接,以便在同一个连接上发送多个请求和接收多个响应。

持久连接(长连接)

  • HTTP/1.1:在 HTTP/1.1 协议中,默认使用持久连接。当客户端和服务器都不明确指定关闭连接时,连接将保持打开状态,以便后续的请求和响应可以复用同一个连接。
  • HTTP/1.0:在 HTTP/1.0 协议中,默认连接是非持久的。如果希望在 HTTP/1.0上实现持久连接,需要在请求头中显式设置 Connection: keep-alive。

语法格式

  • Connection: keep-alive:表示希望保持连接以复用 TCP 连接
  • Connection: close:表示请求/响应完成后,应该关闭 TCP 连接

下面附上一张关于 HTTP 常见 header 的表格

字段名含义样例
Accept客户端可接受的
响应内容类型
Accept: text/html,application/xhtml+xml,app
lication/xml;q=0.9,image/webp,image /apng,*/*;q=0.8
Accept
Encoding
客户端支持的数
据压缩格式
Accept-Encoding: gzip, deflate, br
Accept
Language
客户端可接受的
语言类型
Accept-Language: zh CN,zh;q=0.9,en;q=0.8
Host请求的主机名和
端口号
Host: www.example.com:8080
User-Agent客户端的软件环
境信息
User-Agent: Mozilla/5.0 (Windows NT10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, likeGecko) Chrome/91.0.4472.124
Safari/537.36
Cookie客户端发送给服
务器的 HTTP
cookie 信息
Cookie: session_id=abcdefg12345;user_id=123
Referer请求的来源 URLReferer: http://www.example.com/previous_page.html
Content-Type实体主体的媒体
类型
Content-Type: application/x-wwwform-urlencoded (对于表单提交) 或
Content-Type: application/json (对于JSON 数据)
Content-Length实体主体的字节
大小
Content-Length: 150
Authorization认证信息, 如用
户名和密码
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== (Base64
编码后的用户名:密码)
Cache-Control缓存控制指令请求时: Cache-Control: no-cache 或 Cache-Control: max-age=3600; 响应时: Cache-Control: public, max age=3600
Connection请求完后是关闭
还是保持连接
Connection: keep-alive 或 Connection: close
Date请求或响应的日
期和时间
Date: Wed, 21 Oct 2023 07:28:00 GMT
Location重定向的目标
URL(与 3xx 状
态码配合使用)
Location: http://www.example.com/new_location.html (与 302 状态码配合使用)
Server服务器类型Server: Apache/2.4.41 (Unix)
Last-Modified资源的最后修改
时间
Last-Modified: Wed, 21 Oct 2023 07:20:00 GMT
ETag资源的唯一标识
符, 用于缓存
ETag: "3f80f-1b6-5f4e2512a4100"
Expires响应过期的日期
和时间
Expires: Wed, 21 Oct 2023 08:28:00 GMT

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/938101.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从 Router 到 Navigation:HarmonyOS 路由框架的全面升级与迁移指南

在本教程中&#xff0c;我们深入探讨了 Router 和 Navigation 在 HarmonyOS 中的用法差异及如何从 Router 切换到 Navigation 的方法。重点涵盖了页面跳转、转场动画、生命周期管理以及跨包路由的实现。 页面结构对比 Router 页面结构 每个页面需要使用 Entry 注解。 页面需要…

账号下的用户列表表格分析

好的&#xff0c;这是您提供的 el-table 组件中所有列的字段信息&#xff0c;以表格形式展示&#xff1a; 列标题 (label)字段属性 (prop)对齐方式 (align)宽度 (width)是否可排序 (sortable)说明IDidcenter100否管理员的唯一标识符头像avatarcenter90否管理员的头像 URL 或路…

luckysheet与superslide冲突解决

[现象]控制台报错、界面无法操作 $是jquery。查看源码&#xff0c;发现mousewheel方法来自插件mousewheel&#xff0c;luckysheet初始应该会将mousewheel挂载在jquery上。 在控制台打印jquery取dom及其方法&#xff0c;结果如下&#xff1a; 不存在mousewheel方法&#xff0c…

windows使用python写的YOLO来实现目标识别

使用labelImg标注&#xff0c;YOLO进行目标训练 一、labelImg工具下载及使用1、下载labelImg&#xff08;目标标注工具[【点我下载】](https://github.com/HumanSignal/labelImg)&#xff09;2、使用labelImg 二、下载及使用YOLO1、下载及使用ultralytics&#xff08;volo[点击…

Java——多线程(上)

一 (线程的介绍) 1 多线程的基本概念 (每个进程由三部分构成——>CPU&#xff0c;Data&#xff0c;Code&#xff0c;进程之间完全独立&#xff0c;内存隔离) (运行在进程内的&#xff0c;一个进程可以包含多个线程&#xff0c;线程之间是可以并行的&#xff0c;并且共享相…

SpringBoot3+graalvm:整合并打包为可执行文件

原文网址&#xff1a;SpringBoot3graalvm&#xff1a;整合并打包为可执行文件-CSDN博客 简介 本文介绍SpringBoot3如何整合graalvm&#xff0c;并打包为可执行文件。Windows和Linux都打包。 版本 springboot3.3.6 graalvm21&#xff08;包含JDK21&#xff08;21是最新的LT…

【Bolt.new + PromptCoder】三分钟还原油管主页

【Bolt.new PromptCoder】三分钟还原油管主页 PromptCoder官网&#xff1a;PromptCoder Bolt官网&#xff1a;https://bolt.new/ Bolt 是什么&#xff1f; Bolt.new 是一个提供创建全栈网络应用服务的平台。它允许用户通过提示&#xff08;Prompt&#xff09;、运行&#x…

ubuntu下anconda装pytorch

1、禁用nouveau sudo vim /etc/modprobe.d/blacklist.conf 在文件最后部分插入以下两行内容 blacklist nouveau options nouveau modeset0 更新系统 sudo update-initramfs -u 重启系统 2、装nvidia驱动 卸载原来驱动 sudo apt-get remove nvidia-* &#xff08;若安装…

QT数据库(四):QSqlRelationalTableModel 类

关系数据库概念 例如下列departments、majors、studInfo 这 3 个数据表之间存在关系。 主键与外键 标记“**”的是主键字段&#xff0c;标记“*”的是外键字段。主键字段是一个数据表中表示记录唯一性的字段&#xff0c;例如 studInfo 数据表中的 studID 字段。外键字段是与其…

【Linux】-学习笔记10

第八章、Linux下的火墙管理及优化 1.什么是防火墙 从功能角度来讲 防火墙是位于内部网和外部网之间的屏障&#xff0c;它按照系统管理员预先定义好的规则来控制数据包的进出 从功能实现角度来讲 火墙是系统内核上的一个模块netfilter(数据包过滤机制) …

SpringBoot 手动实现动态切换数据源 DynamicSource (中)

大家好&#xff0c;我是此林。 SpringBoot 手动实现动态切换数据源 DynamicSource &#xff08;上&#xff09;-CSDN博客 在上一篇博客中&#xff0c;我带大家手动实现了一个简易版的数据源切换实现&#xff0c;方便大家理解数据源切换的原理。今天我们来介绍一个开源的数据源…

Crawl4AI:一个为大型语言模型(LLM)和AI应用设计的网页爬虫和数据提取工具实战

这里写目录标题 一、crawl4AI功能及简介1、简介2、特性 二、项目地址三、环境安装四、大模型申请五、代码示例1.生成markdown2.结构化数据 一、crawl4AI功能及简介 1、简介 Crawl4AI 是一个开源的网页爬虫和数据抓取工具&#xff0c;一个python项目&#xff0c;主要为大型语言…

【银河麒麟高级服务器操作系统】有关dd及cp测试差异的现象分析详解

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn dd现象 使用银河麒麟高级服务器操作系统执行两次…

sqli-labs靶场第26-30关

第26关 这关将逻辑运算符&#xff0c;注释符以及空格给过滤了 我们先使用单引号进行闭合 这时我们查看源代码可以看到这一关过滤了很多字符 可以看到这里将or and / -- # 空格等字符都被注释了 空格被过滤了我们可以使用()来代替&#xff0c;and和or可以使用双写来绕过 因为…

ik分词器了解 和 通过zip安装包的方式 将ik分词器安装到elasticsearch中

目录 1. ik分词器的作用&#xff08;效果&#xff09; &#xff08;1&#xff09;标准分析器效果 &#xff08;2&#xff09;ik_smart分词 &#xff08;3&#xff09;ik_max_word分词 2. 首先根据自己的elasticsearch的版本下载对应的ik分词器版本 3. 将下载好的ik分词器…

实景视频与模型叠加融合?

[视频GIS系列]无人机视频与与实景模型进行实时融合_无人机视频融合-CSDN博客文章浏览阅读1.5k次&#xff0c;点赞28次&#xff0c;收藏14次。将无人机视频与实景模型进行实时融合是一个涉及多个技术领域的复杂过程&#xff0c;主要包括无人机视频采集、实景模型构建、视频与模型…

【解决】k8s使用kubeadm初始化集群失败问题整理

执行提示命令&#xff0c;查看报错信息 journalctl -xeu kubelet1、错误&#xff1a;running with swap on is no 报错 "command failed" err"failed to run Kubelet: running with swap on is no 解决&#xff1a; swap未禁用&#xff0c;需要禁用swap&…

aws(学习笔记第十七课) SQS Amazon Simple Queue Service服务

aws(学习笔记第十七课) SQS Amazon Simple Queue Service服务 学习内容&#xff1a; 使用SQS Amazon Simple Queue Service服务整体代码&#xff08;nodejs的通常工程&#xff09;代码动作 1. 使用SQS Amazon Simple Queue Service服务 利用应用程序来学习SQS 创建S3$ aws s…

qt-C++笔记之父类窗口、父类控件、对象树的关系

qt-C笔记之父类窗口、父类控件、对象树的关系 code review! 参考笔记 1.qt-C笔记之父类窗口、父类控件、对象树的关系 2.qt-C笔记之继承自 QWidget和继承自QObject 并通过 getWidget() 显示窗口或控件时的区别和原理 3.qt-C笔记之自定义类继承自 QObject 与 QWidget 及开发方式…

VMware ubuntu12.04怎么设置静态IP联网

记得刚开始学习嵌入式就是从ubuntu12.04的环境开始学习的C语言&#xff0c;当时没有弄清楚怎么设置静态IP联网&#xff0c;现在写一篇文章。 1.首先&#xff0c;关闭ubuntu的网络&#xff1b; 2.电脑使用的是wifi,将VMware桥接到该网卡上&#xff1b; 3.在虚拟机设置里面选择桥…