Linux网络(九):从 URL 到 HTTP 报文:彻底搞懂 HTTP 请求与响应,并手写一个简单的 HTTP 服务器


◆ 博主名称: 小此方-CSDN博客 大家好,欢迎来到小此方的博客。
⭐️网络系列个人专栏: 【主题曲】计算机网络
⭐️此方的GitHub: github_此方
⭐️ 我们思考 (Rethink) · 我们重建 (Rebuild) · 我们记录 (Record)


文章目录


概要&序論

  Hello,大家好,我是此方。在第七期的时候,我们讲解了如何去自定义一个应用层协议,虽然我们说,应用层协议是我们程序员自己定的 。但实际上,已经有大佬们定义了一些现成的,又非常好用的应用层协议,供我们直接参考使用。HTTP(超文本传输协议)就是其中之一。 本文开始的连续多篇内容,我们就开始详细讲解HTTP协议。

一、什么是HTTP协议?

  给一个课本定义 :在互联网世界中,HTTP(HyperText Transfer Protocol,超文本传输协议)是一个至关重要的协议。

它定义了客户端(如浏览器)与服务器之间如何通信,以交换或传输超文本(如HTML文档)。

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

二、从分析URL(网址)初步看HTTP协议

2.1协议

  前面这个https 或者说 http表示获取资源采用的协议。像一些成熟的协议,端口号都是固定的,比如:https: 443,http: 80,ssh: 22。这也印证了:0~1023的端口号不能随便用。

2.2域名

  你可以简单的理解,域名就是IP地址。域名转化为IP地址访问,就是去访问这个公司的服务器。直接用这个公司的IP为什么不好?因为IP地址没有表意性。

2.3资源访问路径

2.3.1在网络中,如何定义 "资源"

  先来理解一下什么是资源

  你想想,人的上网行为可以概括为哪些?就两种

  1. 从远端拿下来数据。
  2. 将自己本地的数据上传到远端。

  这些数据可以是什么呢?短视频、视频、网页、图片、音频...... 。没有获取它的时候,这些资源在哪里?答案是:Linux 服务器内部 。以什么形式存在呢?答案是:一个文件就是"资源"。

2.3.2网络资源存放的路径

  回到这里,于是我们看到,/Z2314246476?spm=1000.2115.3001.5343就可以理解为一种资源存放的路径。前面的这个"/",就是Web根目录,注意:Web根目录不是Linux的根目录,这里必须先埋下一个伏笔。 。中间的这些"/",就是Linux的路径分隔符。资源就是服务器下对应的资源。

2.4我们如何访问资源

  首先,运营商给我们建设了域名服务器。我们用浏览器输入URL访问这个域名服务器,域名服务器解析域名,返回一个IP地址。然后浏览器就可以拿着这个IP地址 + 端口号(取决于你采用的协议HTTP或是HTTPS)访问对应的服务器,根据域名后面的资源访问路径获取对应的资源。

运营商的域名服务器里存着一本庞大的"电话簿"------DNS 记录表。当你在浏览器输入域名时,服务器就会在这本"电话簿"里检索,将域名精准翻译成对应的 IP 地址。

  我们去ping一个百度的网址,可以看到正在 Ping www.a.shifen.com 2409:8c54:870:187:0:ff:b0d9:bb1c 具有 32 字节的数据: ,这里面的2409:8c54:870:187:0:ff:b0d9:bb1c 就是IP地址,IP地址+端口号,也就是协议+域名就可以访问目标服务器。

Tips:为什么这个IP地址看起来这么奇怪?因为这是IPv6的地址。我们平常看到的是IPv4

bash 复制代码
PS C:\Windows\System32\WindowsPowerShell\v1.0> ping www.baidu.com

正在 Ping www.a.shifen.com [2409:8c54:870:187:0:ff:b0d9:bb1c] 具有 32 字节的数据:
来自 2409:8c54:870:187:0:ff:b0d9:bb1c 的回复: 时间=551ms
来自 2409:8c54:870:187:0:ff:b0d9:bb1c 的回复: 时间=529ms
来自 2409:8c54:870:187:0:ff:b0d9:bb1c 的回复: 时间=352ms
来自 2409:8c54:870:187:0:ff:b0d9:bb1c 的回复: 时间=597ms

2409:8c54:870:187:0:ff:b0d9:bb1c 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 352ms,最长 = 597ms,平均 = 507ms
PS C:\Windows\System32\WindowsPowerShell\v1.0>

做一些历史补充,以下框出来的两个字段曾经有,现在已经被废弃了。

2.5 总结

  从 HTTP 的角度来看,"资源"本质上就是存储在 Linux 服务器特定路径下的文件。

  我们在 URL 中看到的协议与端口号(http/https:port)域名(映射具有唯一性的 IP 地址)以及路径(目标机器上特定路径的文件) ,这三者共同构成了全网内唯一的文件定位。

  因此,超文本传输协议的本质就是用来传递文件的,其底层依然是基于 Socket 实现的网络通信!!!!

Tips:urlencode和urldecode(补充内容)

  我们尝试去搜索一下这个内容:hello: //@world

  可以看到,在搜索框中输入的特殊字符在 URL 中变成了像 %20%3A%2F%40 这样的一串字符。

  像 :/@ 以及空格等字符,在 URL 中具有特殊的用途或分隔含义。如果这些字符直接出现在 URL 的参数中,会导致客户端或服务器在解析 URL 时发生混淆,进而引发解析失败。

  为了避免歧义,客户端(如浏览器)在向服务器发送请求前,会自动将 URL 中的特殊字符转码为十六进制形式,这个转码的过程就称为 urlencode 。当服务器接收到请求后,再将其还原为原始字符,这个解码的过程则称为 urldecode

  这种由浏览器负责 urlencode 编码、服务器负责 urldecode 解码的交互模式,正是典型的 B/S(Browser/Server)架构模式。我们以前写的是C/S。

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

三、HTTP请求与响应格式

3.1Http请求的格式

3.1.1请求格式的内容有哪些

  找到了一个HTTP请求报文,我们来分析一下。

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

HTTP的底层是TCP,我们在后面的代码中会体会到。

  把上面的报文抽象一下,我们会得到这样一个结构图:

3.1.2请求格式的细节

  整个 HTTP 请求报文在网络传输中,本质上就可以被理解为一个具有多行的字符串。

3.1.2.1HTTP协议如何做到报头和有效载荷分离?

  HTTP 协议以空行(\r\n)作为报头与有效载荷的分隔符。在解析报文时,系统按行读取,当读取到一个只有换行符的空行时,就意味着请求报头(Header)部分结束,紧接着后续的内容即为有效载荷(Body)。

3.1.2.2HTTP协议如何做序列化和反序列化

  HTTP 协议的序列化与反序列化过程非常直接,它并没有依赖任何复杂的第三方库,而是直接使用特殊字符进行字符串的拼接与切割。在发送端,将内存中的结构化请求数据按规范拼接为字符串(序列化);在接收端,则通过匹配特殊字符将该字符串重新解析提取为结构化对象(反序列化)。

3.2Http响应的格式

3.2.1响应格式的内容有哪些

  找到了一个HTTP响应报文,我们来分析一下。

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

四、设计一个简单的HTTP服务器------参考源码

  都是手写代码,可能会有bug,如果有,非常欢迎大佬指出私信。量真的太大了,我把仓库贴一下: (目前仓库还在建设中,Readme还没有写。)Konata's Network-Programming


好的本期内容就到这里,如果对你有帮助,还不要忘记点赞三联支持。我是此方,我们下期再见。bye!

相关推荐
xixiaoyunya1 小时前
数据备份方式全解析:三个核心维度的分类原理与组合策略
网络
前端世界1 小时前
Linux服务器实战:日志越来越大怎么办?用Logrotate+DNS解决日志管理与内网访问问题
linux·服务器·chrome
小羊没烦恼!1 小时前
Office文件的奥秘——.NET平台下不借助Office实现Word、Powerpoint等文件的解析(完)
java·大数据·前端·网络·word·powerpoint·.net
小此方1 小时前
Linux网络(十):HTTP请求是如何被服务器解析的?从请求报文、路径处理到响应状态码与异常处理
linux·服务器·网络
少司府1 小时前
Linux系统篇(一)指令篇·一:初识Linux及其基本指令
linux·运维·服务器·网络·阿里云·linux系统
Zixhy3 小时前
手撕Reactor模型实现同步高并发服务器及Muduo网络库深入解析
linux·服务器·网络·数据库·c++
晴天163 小时前
前端 postMessage 使用场景
前端·javascript·网络
迷途之人不知返3 小时前
【进程】-4-进程状态(2):Linux中的进程状态
linux
IMPYLH4 小时前
HTML 的 <samp> 元素
前端·网络·html