| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> HTTP简介 -> 正文阅读 |
|
[网络协议]HTTP简介 |
1.HTTP报文
????????HTTP 报文是在
HTTP
应用程序之间发送的数据块(用于 HTTP
协议交互的信息)。
????????请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。
1.1.0 开发者模式下的http事务?
Request URL:请求的地址。
Request Method: 请求的方式。
Status Code: 请求的状态码。
Remote Address
:访问目标
URL
解析出来的
IP
地址,
443
:表示当前
https
协议。
Referrer Policy : Referrer
用户指明当前请求的来源页面,对于同源的请求,会发送完整的url
作为引用地址,防盗链。
请求报文信息
? accept:请求可以支持的响应格式列表信息 accept-encoding:告知服务器本地浏览器支持是压缩方式 ?
sec-fetch-dest
:期望获得什么类型的资源
sec-fetch-mode
:
navigate
,表示这是一个浏览器的页面切换请求
sec-fetch-site
:表示一个请求发起的来源和目标资源来源之间的关系,
cross-site:跨域请求,
same-origin
:同源请求。
sec-fetch-user
:?
1
表示的
true
upgrade-insecure-requests :1,
表示当前浏览器告诉服务器,浏览器是可以处理https
请求的,即使访问的
https
请求中又包含了其他的
http
请求。
user-agent
:描述浏览器的信息
响应报文信息
?
server
:
web
应用程序部署的容器,
openresty
:封装了
Nginx
以及第三方的类库,Lua
语言,
redis
等等。
vary
:
accept-Encoding
,告诉代理服务器缓存两种版本的资源(压缩、不压缩)
1.1.2 报文的组成部分
????????HTTP 报文是简单的格式化数据块。 每条报文都包含一条来自客户端的请求,或者一条来自服务器的响应。 它们由三个部分组成:
1.
对报文进行描述的起始行(
start line
)
2.
包含属性的首部(
header
)块
3.
以及可选的包含数据的主体(
body
) 部分
1.1.3 HTTP请求
????????
(1)起始行
HTTP
请求是由客户端发出的消息,用来使服务器执行动作。
起始行
(start-line) 包含三个元素:
1.
一个
HTTP
方法
,一个动词
([
GET
,
PUT
或者
POST
)
或者一个名词
(
像
HEAD或者 OPTIONS
),
描述要执行的动作
.
例如
,
GET
表示要获取资源,
POST
表 示向服务器推送数据 (
创建或修改资源
)
。
2.
请求目标
(request target)
,通常是一个
URL
,或者是协议、端口和域名的绝对路径,通常以请求的环境为特征。请求的格式因不同的 HTTP
方法而 异。它可以是:一个完整的URL
,被称为
绝对形式
(absolute form)
,主要在使用
GET 方法连接到代理时使用。
GET http://developer.mozilla.org/en
-US/docs/Web/HTTP/Messages HTTP/1.1
由域名和可选端口(以
':'
为前缀)组成的
URL
的
authority component,称为
authority form
。 仅在使用
CONNECT
建立
HTTP
隧 道时才使用。
CONNECT developer.mozilla.org:80 HTTP/1.1
星号形式
(asterisk form)
,一个简单的星号
(
'*'
)
,配合
OPTIONS
方法 使用,代表整个服务器。
OPTIONS * HTTP/1.1
3.
HTTP
版本
(HTTP version
)
,
定义了剩余报文的结构,作为对期望的响应版本的指示符。
(2)
Headers
来自请求的
HTTP headers
遵循和
HTTP header
相同的基本结构:不区分大小写的字符串,紧跟着的冒号 (':')
和一个结构取决于
header
的值。 整个header(包括值)由一行组成,这一行可以相当长。
(3)
Body
请求的最后一部分是它的
body
。不是所有的请求都有一个
body
:例如获取资 源的请求,GET
,
HEAD
,
DELETE
和
OPTIONS
,通常它们不需要
body
。 有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST
请求(包含HTML 表单数据)。
1.1.4 HTTP响应
(1)状态行
HTTP
响应的起始行被称作
状态行
(status line)
,包含以下信息:
1.
协议版本
,通常为
HTTP/1.1
。
2.
状态码
(status code)
,表明请求是成功或失败。常见的状态码是
200
,
404
,或
302
。
3.
状态文本
(status text)
。一个简短的,纯粹的信息,通过状态码的文本描 述,帮助人们理解该 HTTP
消息。 一个典型的状态行看起来像这样: HTTP/1.1 404 Not Found
。
(2)
Headers
响应的
HTTP headers
:不区分大小写的字符串,紧跟着的冒号
(
':'
)
和一个结构取决于 header
类型的值。 整个
header
(包括其值)表现为单行形式。
(3)
Body
响应的最后一部分是
body
。不是所有的响应都有
body
。
1.1.5 HTTP请求方法请求的起始行以方法作为开始, 方法用来告知服务器要做些什么。
(1)
GET
GET
是最常用的方法。 通常用于请求服务器发送某个资源。
HTTP/1.1
要求服务器实现此方法。
(2)HEAD
HEAD
方法与
GET
方法的行为很类似, 但服务器在响应中只返回首部。 不会返 回实体的主体部分。 这就允许客户端在未获取实际资源的情况下, 对资源的首部进行检查。 使用 HEAD
, 可以:
? 在不获取资源的情况下了解资源的情况(比如, 判断其类型) ;
?
通过查看响应中的状态码, 看看某个对象是否存在;
?
通过查看首部, 测试资源是否被修改了。
服务器开发者必须确保返回的首部与
GET
请求所返回的首部完全相同。 遵循HTTP/1.1 规范, 就必须实现
HEAD
方法。
(3)
PUT
与
GET
从服务器读取文档相反,
PUT
方法会向服务器写入(更新)文档。
PUT
方法的语义就是让服务器用请求的主体部分来创建一个由所请求的
URL
命名的新文档, 或者, 如果那个 URL
已经存在的话, 就用这个主体来替代它。
(4)
POST
POST
方法起初是用来向服务器输入数据的 。 实际上, 通常会用它来支持HTML的表单。 表单中填好的数据通常会被送给服务器处理。
(5)
TRACE
TRACE
客户端发起一个请求时, 这个请求可能要穿过防火墙、 代理、 网关或其他一些应用程序。 每个中间节点都可能会修改原始的 HTTP
请求。
TRACE
方法允许客户端在最终将请求发送给服务器时, 看看它变成了什么样子。TRACE
请求会在目的服务器端发起一个“
环回
”
诊断。 行程最后一站的服务器会弹回一条TRACE 响应, 并在响应主体中携带它收到的原始请求报文。 这样客户端就可以查看在所有中间 HTTP
应用程序组成的请求
/
响应链上, 原始报文是否, 以及
如何被毁坏或修改过
TRACE
方法主要用于诊断; 也就是说, 用于验证请求是否如愿穿过了请求
/
响应链。
(6)
OPTIONS
OPTIONS
方法请求
Web
服务器告知其支持的各种功能。 可以询问服务器通常支持哪些方法, 或者对某些特殊资源支持哪些方法。
(7)
DELETE
DELETE
方法所做的事情就是请服务器删除请求
URL
所指定的资源。
1.1.6 状态码
????????方法是用来告诉服务器做什么事情的, 状态码则用来告诉客户端,事情执行的结果。状态码位于响应的起始行中。 服务器通常会返回一个数字状态和一个可读的状态。 数字码便于程序进行差错处理, 而原因短语则更便于人们理解。
? 200 到
299
之间的状态码表示成功。
? 300 到
399
之间的代码表示资源已经被移走
? 400 到
499
之间的代码表示客户端的请求出错
? 500 到
599
之间的代码表示服务器出错
(1)成功状态码
客户端发起请求时, 这些请求通常都是成功的。 服务器有一组用来表示成功的状态码, 分别对应于不同类型的请求。
(2)重定向状态码
重定向状态码要么告知客户端使用替代位置来访问他们所感兴趣的资源, 要么就提供一个替代的响应而不是资源的内容。
如果资源已被移动, 可发送一个重定向状态码告知客户端资源已被移走, 以及现在可以在哪里找到目标资源。
? 301 redirect: 301 代表永久性转移
(Permanently Moved)
? 302 redirect: 302 代表暂时性转移
(Temporarily Moved )
301
和
302
状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL
地址,这个地址可以从响应的
Location
首部中获取(用户看到的效果就是他输入的地址A
瞬间变成了另一个地址
B
)
——
这是它们的共同点。
他们的不同在于。
301
表示旧地址
A
的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302
表示旧地址
A
的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A
跳转到地址
B
,搜索引擎会抓取新的内容而保存旧的网址。
(3)客户端错误状态码
有时客户端会发送一些服务器无法处理的东西, 比如格式错误的请求报文, 或者最常见的是, 请求一个不存在的 URL
。浏览网页时, 我们都看到过臭名昭著的 404 Not Found
错误码
——
这只是服务器在告诉我们, 它对我们请求的资源一无所知。
(4)服务器错误状态码
有时客户端发送了一条有效请求, 服务器自身却出错了。 这可能是客户端碰上了服务器的缺陷, 或者服务器上的子元素, 比如某个网关资源, 出了错。代理尝试着代表客户端与服务器进行交流时, 经常会出现问题。
2 连接管理2.1 TCP连接
HTTP
通信由
TCP/IP
承载的,
TCP/IP
是全球计算机及网络设备都在使用的一种常用的分组交换网络分层协议集。 客户端应用程序可以打开一条 TCP/IP
连接,连接到可能运行在世界任何地方的服务器应用程序。 一旦连接建立, 在客户端和服务器的计算机之间交换的报文就永远不会丢失、 受损或失序。
2.1.1 三步握手
TCP
协议目的是为了保证数据能在两端准确连续的流动,可以想象两个建立起TCP通道的设备就如同接起了一根水管,数据就是水管中的水由一头流向另一头。然而TCP
为了能让一个设备连接多根
“
水管
”
,让一个设备能同时与多个设备交互信息,它必须要保证不同水管之间不会产生串联或相互影响为了确保数据能够正确分发,TCP
用一种叫做
TCB
,也叫传输控制块的数据结构把发给不同设备的数据封装起来,我们可以把该结构看做是信封。一个TCB
数据块包含了数据发送双方对应的socket
信息以及拥有装载数据的缓冲区。
在两个设备要建立连接发送数据之前,双方都必须要做一些准备工作,分配内存建立起TCB
数据块就是连接建立前必须要做的准备工作。
(0)准备工作
最开始的时候客户端和服务器都是处于
CLOSED
状态。主动打开连接的为客户端,被动打开连接的是服务器。
TCP
服务器进程先创建传输控制块
TCB
,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN
(监听)状态
(1)一次握手:
TCP
客户进程也是先创建传输控制块
TCB
,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1
,同时选择一个初始序列号
seq=x
。此时,TCP
客户端进程进入了
SYN-SENT
(同步已发送状态)状态。
TCP
规定,SYN
报文段(
SYN=1
的报文段)不能携带数据,但需要消耗掉一个序号。
(2)二次握手:
TCP
服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1
,
SYN=1
,确认号是
ack=x+1
,同时也要为自己初始化一个序列号seq=y,此时,
TCP
服务器进程进入了
SYN-RCVD
(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
ACK
为
1
表示确认号有效,为
0
表示报文中不包含确认信息
(3)三次握手:
TCP
客户进程收到确认后,还要向服务器给出确认。确认报文的
ACK=1
,ack=y+1,自己的序列号
seq=x+1
,此时,
TCP
连接建立,客户端进入ESTABLISHED(已建立连接)状态。
TCP
规定,
ACK
报文段可以携带数据,但是如果不携带数据则不消耗序号。当服务器收到客户端的确认后也进入established
状态,此后双方就可以开始通信了。
注:
tcp
建立连接需要三次握手,
SYN
是发送标志位,
ACK
是确认标志位。
为什么TCP客户端最后还要发送一次确认呢?
主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
为什么要
3
次握手
?
第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。
第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。 第一、二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力是否正常。而在第三次握手时,服务端收到了客户端对第二次握手作的回应。从服务端的角度,我在第二次握手时的响应数据发送出去了,客户端接收到了。所以,我的发送能力是正常的。而客户端的接收能力也是正常的。
2.1.2?四次挥手
数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于established
(表示连接已经建立)状态,然后客户端主动关闭,服务器被动关闭。
(1)
TCP
客户端发送一个
FIN
,用来关闭客户到服务器的数据传送。
(2) 服务器收到这个
FIN
,它发回一个
ACK
,确认序号为收到的序号加
1
。和 SYN一样,一个
FIN
将占用一个序号。
(3) 服务器关闭客户端的连接,发送一个
FIN
给客户端。
(4) 客户端发回
ACK
报文确认,并将确认序号设置为收到序号加
1
。
为什么建立连接是三次握手,关闭连接确是四次挥手呢?
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文 后,把ACK和SYN放在一个报文里发送给客户端。 关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必已经将全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 8:47:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |