HTTP协议透析

Web 使用一种名为 HTTP(HyperText Transfer Protocol,超文本传输协议 1)的协议作为规范,完成从客户端到服务器端等一系列运作流程。可以说,Web 是建立在 HTTP 协议上通信的,所有的WWW文件都必须遵守这个标准。HTTP 协议和 TCP/IP 协议族内的其他众多的协议相同,用于客户端和服务器之间的通信,设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。HTTP 协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。

TCP/IP协议

数据封装过程

从应用层至物理层,数据是一层层封装,封装的方式一般都是在原有数据的前面加一个数据控制头,数据封装格式如下:

 

TCP三层握手 & 数据通信 & 四次挥手

TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道。

三次握手

第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。

 

传输数据过程

a.超时重传

超时重传机制用来保证TCP传输的可靠性。每次发送数据包时,发送的数据报都有seq号,接收端收到数据后,会回复ack进行确认,表示某一seq号数据已经收到。发送方在发送了某个seq包后,等待一段时间,如果没有收到对应的ack回复,就会认为报文丢失,会重传这个数据包。

b.快速重传

接受数据一方发现有数据包丢掉了。就会发送ack报文告诉发送端重传丢失的报文。如果发送端连续收到标号相同的ack包,则会触发客户端的快速重传。比较超时重传和快速重传,可以发现超时重传是发送端在傻等超时,然后触发重传;而快速重传则是接收端主动告诉发送端数据没收到,然后触发发送端重传。

c.流量控制

这里主要说TCP滑动窗流量控制。TCP头里有一个字段叫Window,又叫Advertised-Window,这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。 滑动窗可以是提高TCP传输效率的一种机制。

d.拥塞控制

滑动窗用来做流量控制。流量控制只关注发送端和接受端自身的状况,而没有考虑整个网络的通信情况。拥塞控制,则是基于整个网络来考虑的。考虑一下这样的场景:某一时刻网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,但是,重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,于是,这个情况就会进入恶性循环被不断地放大。试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成“网络风暴”,TCP这个协议就会拖垮整个网络。为此,TCP引入了拥塞控制策略。拥塞策略算法主要包括:慢启动,拥塞避免,拥塞发生,快速恢复。a

四次握手

第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但此时主动关闭方还可以接受数据。

第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。

第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。

第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。

URI 和 URL

与 URI(统一资源标识符)相比,我们更熟悉 URL(Uniform Resource Locator,统一资源定位符)。URL 正是使用 Web 浏览器等访问 Web 页面时需要输入的网页地址。比如,下图的 http://baidu.com/ 就是 URL。

URI 是 Uniform Resource Identifier 的缩写。在充分理解的基础上,也可用 URL 替换 URI。RFC2396 分别对这 3 个单词进行了如下定义。

  1. Uniform,规定统一的格式,
  2. Resource,资源的定义,除了文档文件、图像或服务
  3. Identifier,标识符,

RFC3986:统一资源标识符(URI)通用语法:

HTTP请求方法

列出了 HTTP/1.0 和 HTTP/1.1 支持的方法

方法           说明                             支持的 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

持久连接节省通信量

为解决上述 TCP 连接的问题,HTTP/1.1 和一部分的 HTTP/1.0 想出了持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或HTTP connection reuse)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。它好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。

无状态(stateless)与Cookie

HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了 Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。

Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。

服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。

请求及响应报文的结构

下请求报文和响应报文的结构如下,HTTP 报文大致可分为报文首部和报文主体两块。两者由最初出现的空行(CR+LF)来划分。通常,并不一定要有报文主体。

请求行

方法、URI、HTTP版本,如:GET / HTTP/1.1

请求首部字段

HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号“:” 分隔。另外,字段值对应单个 HTTP 首部字段可以有多个值(Keep-Alive: timeout=15, max=100)。

请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。

字段有:Accept、Accept-Charset 、Accept-Encoding、Accept-Language....

通用首部字段

通用首部字段是指请求报文和响应报文双方都会使用的首部。

  • Cache-Control 字段,就能操作缓存的工作机制,如:Cache-Control: max-stale=3600
  • Connection 字段,有控制不再转发给代理的首部字段、管理持久连接,如:Connection:Upgrade(代理服务器收到后将不再发首部字段Upgrade:HTTP/1.1)
  • Date 字段,HTTP/1.1 协议使用在 RFC1123 中规定的日期时间的格式,如:Date: Tue, 03 Jul 2012 04:40:59 GMT
  • Pragma 字段, 是 HTTP/1.1 之前版本的历史遗留字段,仅作为与 HTTP/1.0的向后兼容而定义,如:Pragma: no-cache
  • Trailer 字段,会事先说明在报文主体后记录了哪些首部字段。该首部字段可应用在 HTTP/1.1 版本分块传输编码时,如:Trailer: Expires(在报文主体结束之后也就是分块长度 0 之后,补加首部字段 Expires)
  • Transfer-Encoding 字段, 规定了传输报文主体时采用的编码方式
  • Upgrade, 用于检测 HTTP 协议及其他协议是否可使用更高的版本进行通信
  • Via,是为了追踪客户端与服务器之间的请求和响应报文的传输路径,不仅用于追踪报文的转发,还可避免请求回环的发生,采用的是追加的方式记录(记录了完整的传输路径)

实体首部字段

实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。

字段有:Allow、Content-Encoding、Content-Language、Content-Length 、Content-Type、Content-MD5....

分块传输

发送邮件时,我们可以在邮件里写入文字并添加多份附件。这是因为采用了 MIME(Multipurpose Internet Mail Extensions,多用途因特网邮件扩展)机制,它允许邮件处理文本、图片、视频等多个不同类型的数据。HTTP 协议中也采纳了多部分对象集合,使用 boundary 字符串来划分多部分对象集合指明的各类实体。在boundary 字符串指定的各个实体的起始行之前插入“--”标记(例如:--AaB03x、--THIS_STRING_SEPARATES),而在多部分对象集合对应的字符串的最后插入“--”标记(例如:--AaB03x--、--THIS_STRING_SEPARATES--)作为结束。

multipart/form-data:Web 表单文件上传时

multipart/byteranges:

获取部分内容的范围请求

以前,用户不能使用现在这种高速的带宽访问互联网,。如果下载过程中遇到网络中断的情况,那就必须重头开始。为了解决上述问题,需要一种可恢复的机制。针对范围请求,响应会返回状态码为 206 Partial Content 的响应报文。另外,对于多重范围的范围请求,响应会在首部字段 Content-Type 标明 multipart/byteranges 后返回响应报文。

HTTP状态码

1xx:表明服务端接收了客户端请求,客户端继续发送请求;
2xx:客户端发送的请求被服务端成功接收并成功进行了处理;
3xx:服务端给客户端返回用于重定向的信息;
4xx:客户端的请求有非法内容;
5xx:服务端未能正常处理客户端的请求而出现意外错误。

举例:

“100”  ; 服务端希望客户端继续;
“200”  ; 服务端成功接收并处理了客户端的请求;
“301”  ; 客户端所请求的URL已经移走,需要客户端重定向到其它的URL;
“304”  ; 客户端所请求的URL未发生变化;
“400”  ; 客户端请求错误;
“403”  ; 客户端请求被服务端所禁止;
“404”  ; 客户端所请求的URL在服务端不存在;
“500”  ; 服务端在处理客户端请求时出现异常;
“501”  ; 服务端未实现客户端请求的方法或内容;
“502”  ; 此为中间代理返回给客户端的出错信息,表明服务端返回给代理时出错;
“503”  ; 服务端由于负载过高或其它错误而无法正常响应客户端请求;
“504”  ; 此为中间代理返回给客户端的出错信息,表明代理连接服务端出现超时。

 

看我此篇,他们再也不会那这个为难我了。

参阅资料

  • 图解HTTP <译者:于均良>
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值