计算机网络之应用层协议HTTP

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

应用层协议HTTP

收录于专栏【计算机网络】
本专栏旨在分享学习计算机网络的一点学习笔记,欢迎大家在评论区交流讨论💌 
  

目录

1. HTTP 简单介绍

2. 认识 URL  

urlencode 和 urldecode

3. HTTP 协议请求与响应格式

HTTP 请求

​编辑 HTTP 响应 

​4. HTTP方法

HTTP 常见方法 

GET 方法 

POST 方法 

PUT 方法

HEAD 方法

DELETE 方法

OPTIONS 方法

5. HTTP 的状态码 

6. HTTP 常见 Header 

关于 connection 报头 

7. 实现最简单的 HTTP 服务器 


1. HTTP 简单介绍

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

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

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

2. 认识 URL  

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

urlencode 和 urldecode

像 /? : 等这样的字符, 已经被 url 当做特殊意义理解了. 因此这些字符不能随意出现.

比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.

转义的规则如下 : 

将需要转码的字符转为 : 16 进制, 然后从右到左, 取 4 位 (不足 4 位直接处理), 每 2 位做一位, 前面加上 %, 编码成 %XY 格式

例如 : 

"+" 被转义成了 "%2B"

urldecode 就是 urlencode 的逆过程 

3. HTTP 协议请求与响应格式

HTTP 请求

首行 : [方法] + [url] + [版本]

Header : 请求的属性, 冒号分割的键值对, 每组属性之间使用 \r\n 分隔, 遇到空行表示 Header 部分结束

Body : 空行后面的内容都是 Body. Body 允许为空字符串. 如果 Body 存在, Header 中会有一个 Content-Lengths 属性来标识 Body 的长度

 HTTP 响应 

首行 : [版本号] + [状态码] + [状态码解释]

Header : 请求的属性, 冒号分割的键值对, 每组属性之间使用 \r\n 分隔, 遇到空行表示 Header 部分结束

Body : 空行后面的内容都是 Body. Body 允许为空字符串, 如果 Body 存在, 则在 Header 中会有一个 Content-Length 属性来标识 Body 的长度, 如果服务器返回了一个 html 页面, 那么 html 页面内容就是在 body 中.

4. HTTP方法

方法说明支持的HTTP协议版本
GET获取资源1.0, 1.1
POST传输实体主体1.0, 1.1
PUT传输文件1.0, 1.1
HEAD获取报文首部

1.0, 1.1

DELETE删除文件1.0, 1.1
OPTIONS询问支持的方法1.1
TRACE追踪路径1.1
CONNECT要求用隧道协议连接代理1.1
LINK建立和资源之间的联系

1.0

UNLINE断开连接关系1.0

  

HTTP 常见方法 

GET 方法 

用途 : 用于请求 URL 指定的资源

示例 : GET /index.html HTTP/1.1

特性 : 指定资源服务器端解析后返回响应内容

from表单 : https://www.runoob.com.html/html-froms.html  

POST 方法 

用途 : 用于传输实体的主体, 通常用于提交表单数据.

示例 : POST /submit.cgi HTTP/1.1

特性 : 可以发送大量的数据给服务器, 并且数据包含在请求中.

from表单 :  https://www.runoob.com.html/html-froms.html  

PUT 方法

用途 : 用于传输文件, 将请求文主体中的文件保存到请求 URL 指定的位置

示例 : PUT /example.html HTTP/1.1

特性 : 不太常用, 但在某些情况下, 如 RESTful API 中, 用于更新资源.

HEAD 方法

用途 : 与 GET 方法类似, 烦不烦会报文主体部分, 仅返回响应头

示例 : HEAD /index.html HTTP/1.1

特性 : 用于确认 URL 的有效性以及资源更新的日期时间等

DELETE 方法

用途 : 用于删除文件, 是 PUT 的相反方法

示例 : DELETE /example.html HTTP/1.1

特性 : 按请求 URL 删除指定的资源

OPTIONS 方法

用途 : 用于查询针对请求 URL 指定的资源支持的方法

示例 : OPTIONS * HTTP/1.1

特性 : 返回允许的方法, 如 GET, POST 等 

5. HTTP 的状态码 

类别原因短语
1XXInformational (信息性状态码)接受的请求正在处理
2XXSuccess (成功状态码)请求正常处理完毕
3XXRedirection (重定向状态码)需要进行附加操作加以完成请求
4XXCilent Error (客户端错误状态码)服务器无法处理请求
5XXServer Error (服务器错误状态码)服务器处理请求出错

最常见状态码, 比如 200(OK), 404(Not Found), 403(Forbidden), 302(Redirect, 重定向), 504(Bad Gateway) 

HTTP 状态码 301 (永久重定向) 和 302 (临时重定向) 都依赖 Location 选项, 以下是关于两者依赖 Location 选项的详细说明 : 

HTTP 状态码 301 (永久重定向) :

当服务器返回 HTTP 301 状态码时, 表示请求的资源已经被永久移动到新的位置

这种情况下, 服务器会在响应中添加一个 Location 头部, 用于指定资源的新位置, 这个 Location 头部包含了新的 URL 地址, 浏览器会自动重定向到该地址.

例如, 在 HTTP 响应中, 可能会看到类似于以下的头部信息 : 

HTTP/1.1 301 Moved Permanently\r\n
Location: https://www.new-url.com\r\n

 HTTP 状态码 302 (临时重定向) : 

当服务器返回 HTTP 302 状态码时, 表示请求的资源临时被移动到新的位置.

同样地, 服务器也会在响应中添加一个 Location 头部来指定资源的新位置, 浏览器会暂时使用新的 URL 进行后续的请求, 但不会缓存这个重定向.

例如 : 在 HTTP 响应中, 可能会看到类似于以下的头部信息 : 

HTTP/1.1 302 Found\r\n
Location: https://www.new-url.com\r\n

总结 : 无论是 HTTP 301 还是 HTTP 302 重定向, 都需呀依赖 Location 选项来指定资源的新位置. 这个 Location 选项是一个标准的 HTTP 响应头部, 用于告诉浏览器应该将请求重定向到哪个新的 URL 地址.

6. HTTP 常见 Header 

Content-Type : 数据类型 (text/html 等)

Content-Length : Body 的长度

Host : 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上

User-Agent : 声明用户的操作系统和浏览器版本信息

referer : 当前页面是从哪个页面跳转过来的

Location : 搭配 3XX 状态码使用, 告诉客户端接下来要去哪里访问

Cookie : 用于在客户端存储少量信息, 通常用于实现会话 (session) 的功能

关于 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 连接  

7. 实现最简单的 HTTP 服务器 

实现一个最简单的 HTTP 服务器, 只在网页上输出 "hello world", 只要我们按照 HTTP 协议的要求构造数据, 就很容易做到 

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>void Usage()
{printf("usage : ./server [ip] [port]\n");
}int main(int argc, char* argv[])
{if(argc != 3){Usage();return 1;}int fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");return 1;}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("0.0.0.0");addr.sin_port = htons(atoi(argv[2]));int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));if(ret < 0){perror("bind");return 1;}ret = listen(fd, 10);if(ret < 0){perror("listen");return 1;}for(;;){struct sockaddr_in client_addr;socklen_t len;int client_fd = accept(fd, (struct sockaddr*)&client_addr, &len);if(client_fd < 0){perror("accept");continue;}char input_buf[1024 * 10] = {0}; // 用一个足够大的缓冲区直接把数据读完ssize_t read_size = read(client_fd, input_buf, sizeof(input_buf) - 1);if(read_size < 0){return 1;}printf("[Request] %s", input_buf);char buf[1024] = {0};const char* hello = "<h1>hello world</h1>";sprintf(buf, "HTTP/1.0 200 OK\nContent-Length:%lu\n\n%s", strlen(hello), hello);write(client_fd, buf, strlen(buf));}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch 2.5.1: Bugs修复版发布

一&#xff0c;前言 在深度学习框架的不断迭代中&#xff0c;PyTorch 社区始终致力于提供更稳定、更高效的工具。最近&#xff0c;PyTorch 2.5.1 版本正式发布&#xff0c;这个版本主要针对 2.5.0 中发现的问题进行了修复&#xff0c;以提升用户体验。 二&#xff0c;PyTorch 2…

集合的相关性质与定义

集合 集合 集合描述了一组对象的集合&#xff0c;而映射描述了集合之间的对应关系。 集合 集合是由一组无序的&#xff0c;互不相同的对象组成的整体&#xff0c;集合中的对象称为元素或成员。集合可以用大括号{}表示,元素之间用逗号进行分隔。 定义&#xff1a; 集合 A …

【Golang】Golang基础语法(二):内建变量类型

内建变量类型 Go 的内建变量类型: bool, string(u)int, int8, int16, int32, int64, uintptr(指针, go的指针比C的指针方便很多)byte(8位), rune(32位)(Go的字符类型, 相当于Go的char类型)float32, float64, complex64, complex128 强制类型转换 Golang 当中的类型转换只能…

文件管理:文件描述符fd

1.前置预备 文件 内容 属性访问文件之前&#xff0c;都必须先打开他 #include<stdio.h> int main() { FILE* fpfopen("log.txt","w"); if(fpNULL) { perror("fopen"); return 1; } fclose(fp); return 0…

电脑显示没信号显示屏不亮怎么办?电脑没信号解决方法

电脑没信号显示屏不亮这种故障的原因可能有多种&#xff0c;例如显示器的供电、连接、设置等问题&#xff0c;或者电脑的显卡、内存、硬盘、主板等硬件问题。所以我们想要解决这个问题&#xff0c;也是需要多方面排除找到具体原因然后进行修复。下面将为大家介绍一些常见的电脑…

字节青训Marscode——8:找出整形数组中超过一半的数

问题描述 小R从班级中抽取了一些同学&#xff0c;每位同学都会给出一个数字。已知在这些数字中&#xff0c;某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。 测试样例 样例1&#xff1a; 输入&#xff1a;array [1, 3, 8, 2, 3, 1, 3, 3, 3] 输出…

WPF从本地文件加载界面

在前面的文章中&#xff0c;我介绍过一种报告模板的实现思路。就是用的XAML本地加载。 WPF使用XAML实现报表的一种思路&#xff08;支持外部加载&#xff09; - zhaotianff - 博客园 在另外一篇文章中&#xff0c;介绍了XAML是如何被转换成对象的。 WPF中的XAML是如何转换成对…

Microi吾码产品深度测评:轻量级企业管理应用的全方位剖析

开源低代码平台-Microi吾码-平台简介 技术框架&#xff1a;.NET8 Redis MySql/SqlServer/Oracle Vue2/3 Element-UI/Element-Plus 平台始于2014年&#xff08;基于Avalon.js&#xff09;&#xff0c;2018年使用Vue重构&#xff0c;于2024年10月29日开源 Vue3试用地址&am…

AI后端工程师面试题的内容

AI后端工程师面试题主要包括以下几个方面的内容‌&#xff1a; ‌一、技术基础和项目经验‌&#xff1a; ‌1. 微服务架构的理解和应用‌&#xff1a;请描述你对微服务架构的理解&#xff0c;并举例说明一个你参与过的微服务项目&#xff0c;阐述你在该项目中扮演的角色和所承…

ArrayList如何深究?最简单的数组~

目录 数组 Array 为什么数组索引从0开始呢&#xff1f;为什么不从1开始&#xff1f; ArrayList 成员变量 构造方法 添加和扩容 ArrayList底层的实现原理是什么&#xff1f; 数组和List转换 ArrayList 和 LinkedList区别 底层数据结构 操作数据效率 内存占用 线程安…

前端开发入门指南Day 14 :数据交互(从Ajax到Axios)和工具进阶(JSON、代理、正则表达式)

今天&#xff0c;我们将探索前端开发中最重要的几个实用工具和概念。这些工具就像是前端开发者的瑞士军刀&#xff0c;帮助我们更好地处理数据和实现各种功能。 一、HTTP请求&#xff1a;前后端通信的桥梁 &#x1f309; 为什么需要HTTP请求&#xff1f; 想象你在餐厅点餐&a…

三十一:HTTP多种重定向跳转方式的差异

在现代网站开发中,HTTP 重定向是一种常见的技术,用于将用户的请求从一个 URL 跳转到另一个 URL。重定向机制广泛应用于网站迁移、SEO 优化、以及内容管理系统中。不同的 HTTP 状态码代表不同的重定向方式,每种方式的行为和适用场景各有不同。本文将深入探讨 HTTP 重定向的几…

C++ 分治

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 1.分治法 2.二分搜索 函数传参——数组 3.棋盘覆盖 4.合并排序 5.快速排序 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 1.分治法 基…

anaconda环境下安装第三方库

在 Anaconda 环境中使用 pip install 安装某些包时&#xff0c;可能会出现依赖或环境相关的问题。针对 fastdtw 的安装问题&#xff0c;你可以尝试以下解决方案&#xff1a; 1. 使用 Conda 安装 fastdtw Anaconda 的 conda 包管理器可以更好地处理依赖问题&#xff0c;尤其是…

用函数实现模块化程序设计(七)--数组作为函数参数(排序算法)

调用有参函数时&#xff0c;需要实参&#xff0c;实参可以是常量&#xff0c;变量&#xff0c;表达式&#xff0c;数组元素的作用与变量相当&#xff0c;凡是变量出现的地方都可用数组代替&#xff0c;数组元素可以用作函数实参&#xff0c;数组名可以作实参和形参&#xff0c;…

嵌入式Linux无窗口系统下搭建 Qt 开发环境

嵌入式Linux无窗口系统下搭建 Qt 开发环境 本文将介绍如何在树莓派的嵌入式 Linux 环境下&#xff0c;搭建 Qt 开发环境&#xff0c;实现无窗口系统模式&#xff08;framebuffer&#xff09;下的图形程序开发。 1. 安装 Qt 环境 接下来&#xff0c;安装核心 Qt 开发库以及与 …

基于STM32设计的智能宠物喂养系统(华为云IOT)_273

文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成【4】设计意义【5】国内外研究现状【6】摘要1.2 设计思路1.3 系统功能总结1.4 开发工具的选择【1】设备端开发【2】上位机开发1.5 参考文献1.6 系统框架图1.7 系统原理图1.8 实物图1.9…

C++【PCL】利用矩阵对点云进行刚体变换

/** 功能&#xff1a; 点云刚体变换* 头文件&#xff1a; #include <pcl/common/transforms.h>* 功能函数&#xff1a; pcl::transformPointCloud(*pPointCloudIn, *pPointCloudOut, transform_1);*/#include <pcl/io/ply_io.h>#include <iostream>// pcl #i…

Java项目实战II基于微信小程序的文章管理系统的设计与实现 (开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 在信息爆炸的时代&#xff0c;内容创作与管理已成为众…

Conda 管理python开发环境

同步发布于我的网站 &#x1f680; 故事起因: 在公司使用Requests多任务并行开发时遇到了问题&#xff0c;使用 ProcessPoolExecutor 时不能正常发出网络请求&#xff0c;会卡在网络请求发不出去&#xff0c;但是善于用 ThreadPoolExecutor 时是可以的,纠结了很久&#xff0c;一…