HTTP之原理,长短连接,响应码,三握四挥,八种方法

2022-04-14  本文已影响0人  上善若泪

学习此文章需要有OSI七层模型基础知识

1 HTTP原理

HTTP是一个无状态的协议。无状态是指客户机(Web 浏览器)和服务器之间不需要建立持久的连接,这意味着当一个客户端向服务器端发出请求,然后服务器返回响应(response),连接就被关闭了,在服务器端不保留连接的有关信息.HTTP 遵循请求(Request)/应答(Response)模型。客户机(浏览器)向服务器发送请求,服务器处理请求并返回适当的应答。所有 HTTP 连接都被构造成一套请求和应答

1.1 HTTP协议与TCP/IP协议的关系

HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP有可靠,面向连接的特点。

1.2 无状态的HTTP协议

HTTP协议是无状态的,指的是协议对于 事务处理 没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。

2 长短连接详解

2.1 简介

HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件图像文件CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话

但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接

2.2 TCP短连接

我们模拟一下TCP短连接的情况,clientserver发起连接请求,server接到请求,然后双方建立连接。clientserver发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起 close操作。为什么呢,一般的server不会回复完client后立即关闭连接的,当然不排除有特殊的情况。从上面的描述看,短连接一般只会在 client/server间传递一次读写操作
短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段

2.3 TCP长连接

模拟一下长连接的情况,clientserver发起连接,server接受client连接,双方建立连接。Clientserver完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。
首先说一下TCP/IP详解上讲到的TCP保活功能,保活功能主要为服务器应用提供,服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,则服务器将应该等待客户端的数据,保活功能就是试图在服务器端检测到这种半开放的连接。
如果一个给定的连接在两小时内没有任何的动作,则服务器就向客户发一个探测报文段,客户主机必须处于以下4个状态之一:

  1. 客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常的,服务器在两小时后将保活定时器复位。
  2. 客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务端将不能收到对探测的响应,并在75秒后超时。服务器总共发送10个这样的探测 ,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。
  3. 客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。
  4. 客户机正常运行,但是服务器不可达,这种情况与2类似,TCP能发现的就是没有收到探查的响应。

2.4 长连接短连接操作过程

短连接的操作步骤
建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接
长连接的操作步骤
建立连接——数据传输…(保持连接)…数据传输——关闭连接

2.5 长连接和短连接的优点和缺点

长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。
在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Clientserver之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个客户端连累后端服务。

短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。
长连接和短连接的产生在于client和server采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。

2.6 什么时候用长连接,短连接

长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。
例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好

3 HTTP发送过程解析

3.1 概述

HTTP协议是基于请求/响应的运作方式:

3.2 传输流程

  1. 地址解析
    如用客户端浏览器请求这个页面: http://localhost.com:8080/index.htm 从中分解出协议名、主机名、端口、对象路径等部分,对于我们的这个地址,解析得到的结果如下:
    协议名: http
    主机名: localhost.com
    端口: 8080
    对象路径: /index.htm13/04/2018 Page 165 of 283
    在这一步,需要域名系统 DNS 解析域名 localhost.com,得主机的 IP 地址
  2. 浏览器查找域名的IP地址,DNS查找过程如下:
    浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。
    系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。
    路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存
    ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
    递归搜索ISPDNS服务器从跟域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了

DNS有一点令人担忧,这就是像wikipedia.org 或者 facebook.com这样的整个域名看上去只是对应一个单独的IP地址。还好,有几种方法可以消除这个瓶颈:

  • 循环 DNSDNS查找时返回多个IP时的解决方案。举例来说,Facebook.com实际上就对应了四个IP地址。
  • 负载平衡器 是以一个特定IP地址进行侦听并将网络请求转发到集群服务器上的硬件设备。 一些大型的站点一般都会使用这种昂贵的高性能负载平衡器。
  • 地理 DNS 根据用户所处的地理位置,通过把域名映射到多个不同的IP地址提高可扩展性。这样不同的服务器不能够更新同步状态,但映射静态内容的话非常好。
  • Anycast 是一个IP地址映射多个物理主机的路由技术。 美中不足,Anycast与TCP协议适应的不是很好,所以很少应用在那些方案中
  1. 封装 HTTP 请求数据包
    把以上部分结合本机自己的信息,封装成一个 HTTP 请求数据包
  2. 封装成 TCP包并建立连接
    封装成 TCP 包,建立 TCP 连接(TCP 的三次握手)
  3. 客户机发送请求命
    客户机发送请求命令: 建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是 MIME 信息包括请求修饰符、客户机信息和可内容。
  4. 服务器响应
    服务器接到请求后,给予相应的响应信息, 其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是 MIME 信息包括服务器信息、实体信息和可能的内容。
  5. 服务器关闭TCP连接
    服务器关闭 TCP 连接: 一般情况下,一旦 Web 服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码 Connection:keep-aliveTCP 连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。

大致结构如下所示:


image.png

3.3 请求和响应

3.3.1 一般头字段

一般头字段可用于请求消息响应消息

3.3.2 请求报头域

常见的HTTP请求报头域:

3.3.3 响应结构

HTTP响应由三个部分组成:

响应头结构示例:

3.3.4 HTTP响应码

HTTP响应码:

响应码 响应信息
100 继续,请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分
101 分组交换协议,请求者已要求服务器切换协议,服务器已确认并准备切换
200 OK, 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页
201 已创建,请求成功并且服务器创建了新的资源
202 已接受,服务器已接受请求,但尚未处理
203 非授权信息,服务器已成功处理了请求,但返回的信息可能来自另一来源
204 无内容,请求收到,但返回信息为空
205 重置内容,服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206 部分内容,服务器已经完成了部分用户的GET请求
300 多种选择,请求的资源可在多处得到
301 永久重定向,浏览器会记住,比如说从123.cn——>456.cn,浏览器不会请求123.cn,直接请求456.cn了
302 临时重定向,浏览器不会记住,比如说从123.cn——>456.cn,浏览器每次都会先请求123.cn,然后再请求456.cn
303 查看其他位置,请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码,建议客户访问其他URL或访问方式
304 未修改,自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容
305 使用代理,请求者只能使用代理访问请求的网页。请求的资源必须从服务器指定的地址得到
306 前一版本HTTP中使用的代码,现行版本中不再使用
307 暂时重定向,服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求
400 错误请求,如语法错误
401 未授权,请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应
402 保留有效ChargeTo头响应,要求付费
403 禁止访问 HTTP
404 未找到,没有发现文件、查询或URl
405 方法禁用,用户在Request-Line字段定义的方法不允许
406 不接受,无法使用请求的内容特性响应请求的网页
407 需要代理授权,类似401,用户必须首先在代理服务器上得到授权
408 请求超时,客户端没有在用户指定的时间内完成请求
409 冲突,服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息
410 已删除,如果请求的资源已永久删除,服务器就会返回此响应
411 需要有效长度, 服务器不接受不含有效内容长度标头字段的请求,服务器拒绝用户定义的Content-Length属性请求
412 未满足前提条件,服务器未满足请求者在请求中设置的其中一个前提条件
413 请求实体太大,请求的资源大于服务器允许的大小
414 请求URI太大,请求的资源URL长于服务器允许的长度
415 不支持的媒体类型,请求资源不支持请求项目格式
416 请求范围不符合要求,如果页面无法提供请求的范围,则服务器会返回此状态代码
417 未满足期望值,服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求长,失败的预期
500 内部服务器错误
501 尚未实施,服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码
502 网关错误, 服务器作为网关或代理,从上游服务器收到无效响应
503 不可用的服务,服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态
504 网关超时,服务器作为网关或代理,但是没有及时从上游服务器收到请求
505 HTTP版本未被支持,服务器不支持请求中所用的 HTTP 协议版本

4 三次握手四次挥手

TCP 在传输之前会进行三次沟通,一般称为三次握手,传完数据断开的时候要进行四次挥手

4.1 数据包说明

image.png

数据包说明:

  1. 源端口号(16 位):它(连同源主机 IP 地址)标识源主机的一个应用进程
  2. 目的端口号(16 位):它(连同目的主机 IP 地址)标识目的主机的一个应用进程。这两个值加上 IP 报头中的源主机 IP 地址和目的主机 IP 地址确定唯一一个 TCP 连接
  3. 顺序号seq(32 位): 用来标识从 TCP 源端向 TCP 目的端发送的数据字节流,它表示在这个报文段中的第一个数据字节的顺序号。如果将字节流看作在两个应用程序间的单向流动,则TCP用顺序号对每个字节进行计数。序号是 32bit 的无符号数, 序号到达 2^32-1后又从 0 开始。 当建立一个新的连接时, SYN 标志变1,顺序号字段包含 由这个主机选择的 该连接的初始顺序号 ISN (Initial Sequence Number )
  4. 确认号 ack(32 位): 包含发送确认的一端所期望收到的下一个顺序号。因此,确认序号应当是上次已成功收到数据字节顺序号加 1 。 只有 ACK 标志为 1 时确认序号字段才有效。
    TCP 为应用层提供全双工服务,这意味数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据顺序号。
  5. TCP 报头长度(4 位):给出报头中 32bit 字的数目, 它实际上指明数据从哪里开始。 需要这个值是因为任选字段的长度是可变的。这个字段占 4bit ,因此 TCP 最多有 60 字节的首部。然而,没有任选字段,正常的长度是 20字节
  6. 保留位(6 位):保留给将来使用,目前必须置为 0 。
  7. 控制位(control flags , 6 位):在TCP报头中有 6 个标志比特,它们中的多个可同时被设置为 1 。依次为:
    URG :为 1 表示紧急指针有效,为 0 则忽略紧急指针值。
    ACK :为 1 表示确认号有效,为 0 表示报文中不包含确认信息,忽略确认号字段。
    PSH :为 1 表示是带有 PUSH 标志的数据, 指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满。
    RST : 用于复位由于主机崩溃或其他原因而出现错误的连接。它还可以用于拒绝非法的报文段和拒绝连接请求。一般情况下,如果收到一个 RST 为 1 的报文,那么一定发生了某些问题。
    SYN :同步序号, 为 1 表示连接请求,用于建立连接和使顺序号同步synchronize
    FIN : 用于释放连接,为 1 表示发送方已经没有数据发送了,即关闭本方数据流。
  8. 窗口大小(16 位):数据字节数,表示从确认号开始,本报文的源方可以接收的字节数,即源方接收窗口大小。窗口大小是一个 16bit 字段,因而窗口大小最大为 65535 字节。
  9. 校验和(16 位):此校验和是对整个的 TCP 报文段, 包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。这是一个强制性的字段,一定是由发送端计算和存储, 并由接收端进行验证。
  10. 紧急指针(16 位):只有当 URG 标志置 1 时紧急指针才有效。TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式
  11. 选项:最常见的可选字段是最长报文大小,又称为 MSS(Maximum Segment Size)。每个连接方通常都在通信的第一个报文段(为建立连接而设置 SYN 标志的那个段)中指明这个选项,它指明本端所能接收的最大长度的报文段。选项长度不一定是 32 位字的整数倍,所以要加填充位,使得报头长度成为整字数。
  12. 数据TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段

4.2 三次握手

image.png
  1. 第一次握手:主机 A 发送位码为 syn=1,随机产生 seq number=1234567 的数据包到服务器,主机 B 由 SYN=1 知道, A 要求建立联机;
  2. 第二次握手:主 机 B 收 到 请 求 后 要 确 认 联 机 信 息 , 向 A 发 送 ack number=( 主 机 A 的seq+1),SYN=1,ACK=1,随机产生 seq=7654321 的包
  3. 第三次握手: 主机 A 收到后检查 ack number 是否正确,即第一次发送的 seq number+1,以及位码ACK 是否为 1,若正确, 主机 A 会再发送 ack number=(主机 B 的 seq+1),ACK=1,主机 B 收到后确认seq 值ACK=1 则连接建立成功

4.3 四次挥手

TCP 建立连接要进行三次握手,而断开连接要进行四次。这是由于 TCP 的半关闭造成的。因为 TCP 连接是全双工的(即数据可在两个方向上同时传递)所以进行关闭时每个方向上都要单独进行关闭。这个单方向的关闭就叫半关闭。当一方完成它的数据发送任务,就发送一个 FIN 来向另一方通告将要终止这个方向的连接

首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭


image.png
  1. 关闭客户端到服务器的连接:首先客户端 A 发送一个 FIN,用来关闭客户到服务器的数据传送,然后等待服务器的确认。其中终止标志位 FIN=1,序列号 seq=u
  2. 服务器收到这个 FIN,它发回一个 ACK,确认号 ack 为收到的序号加 1
  3. 关闭服务器到客户端的连接:也是发送一个 FIN 给客户端。
  4. 客户段收到 FIN 后,并发回一个 ACK 报文确认,并将确认序号 seq 设置为收到序号加 1

主机 A 发送 FIN 后,进入终止等待状态, 服务器 B 收到主机 A 连接释放报文段后,就立即给主机 A 发送确认,然后服务器 B 就进入 close-wait 状态,此时 TCP 服务器进程就通知高层应用进程,因而从 A 到 B 的连接就释放了。此时是半关闭状态。即 A 不可以发送给B,但是 B 可以发送给 A。此时,若 B 没有数据报要发送给 A 了,其应用进程就通知 TCP 释放连接,然后发送给 A 连接释放报文段,并等待确认。 A 发送确认后,进入 time-wait
注意,此时 TCP 连接还没有释放掉,然后经过时间等待计时器设置的 2MSL 后, A 才进入到close状态

5 HTTP1.1协议八种方法

5.1 定义

http协议请求由三部分组成,分别是:请求行消息报头请求正文
请求行以一个方法符号开头,以空格分开,后面跟着请求的URI协议的版本,格式如下:

Method Request-URI HTTP-Version CRLF

HTTP/1.1协议中共定义了八种方法(有时也叫动作)来表明Request-URI指定的资源的不同操作方式:

  1. OPTIONS
    返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送*的请求来测试服务器的功能性
  2. HEAD
    向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。
  3. GET
    向特定的资源发出请求。注意:GET方法不应当被用于产生副作用的操作中
  4. POST
    向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改
  5. PUT
    向指定资源位置上传其最新内容。
  6. DELETE
    请求服务器删除Request-URI所标识的资源。
  7. TRACE
    回显服务器收到的请求,主要用于测试或诊断。
  8. CONNECT
    HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

5.2 get和post提交区别

简单来说,本质上区别:

也就是说:

对于GET方式的请求,浏览器会把http headerdata一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)

详细区别:

FORM提交的时候,如果不指定Method,则默认为get请求,Form中提交的数据将会附加在url之后,以?分开与url分开。字母数字字符原样发送,但空格转换为+号,其它符号转换为%XX, 其中XX为该符号以16进制表示的ASCII(或ISOLatin-1)值。get请求请提交的数据放置在HTTP请求协议头中,而post提交的数据则 放在实体数据中;
get方式提交的数据最多只能有1024字节,而post则没有此限制
在表单里使用postget有什么区别
Form里面,可以使用post也可以使用get。它们都是method的合法取值。但是,postget方法在使用上至少有两点不同:

  1. get方法通过URL请求来传递用户的输入。post方法通过另外的形式。
  2. get方式的提交需要用Request.QueryString来取得变量的值,而post方式提交时,必须通过Request.Form来访问提交的内容。
上一篇 下一篇

猜你喜欢

热点阅读