zoukankan      html  css  js  c++  java
  • HTTP学习笔记(一)报文和连接管理

    对TCP/IP协议簇有些了解的同学们应该都知道。TCP/IP协议通过精简ISO网络7层协议(事实上了解历史渊源的话,TCP/IP协议本来目的并非简化ISO的7层协议。仅仅是因为ISO协议簇制定速度慢于互联网通信技术发展的速度,TCP/IP协议已经被各大厂商私下广泛商用化。ISO网络通信标准才制定完毕,所以。鉴于已经广泛应用的TCP/IP协议已经成为各大通信商的实际默认标准。ISO仅仅能作为理论研究标准来供研究之用)来保证我们的网络通信的基础架构。

    自己对HTTP协议的了解基本停留在大学计算机网络的了解程度,一直想深入了解点HTTP的细节,所以近期在拜读《HTTP全然解析》这本著作,认为堪称HTTP解读经典,因为全书的内容太多,一边拜读一边做做笔记加深印象和理解。


    1.TCP协议的贡献

    HTTP协议是TCP/IP协议簇应用层的传输协议。Web浏览器、server和移动client应用层、server交互都是通过HTTP互相通信。HTTP协议是基于传输层可靠的传输数据协议TCP协议实现,并且HTTP无需担心网络通信的细节,它把联网的细节到交给通用、可靠的TCP/IP协议簇的应用层以下几层协议处理。顺便说下,TCP协议向HTTP协议屏蔽了传输数据的细节,TCP至少给HTTP协议的工作提供了一下保证:

    • 无差错的传输数据;
    • 按序传输(数据总是会依照发送的顺序到达);
    • 未分段的数据流(能够在随意时刻以随意尺寸将数据发送出去)。

    2.HTTP协议的基本结构

    讨论HTTP协议的细节。我们离不开HTTP传输协议的基本数据单元,HTTP报文是HTTP应用之间发送的基本单位。HTTP报文都能够分为两类:请求报文(Request Message)和响应报文(Response Message)。

    假设大家对HTTP报文的基本结构还不是非常清楚的话,转到《Http Message结构学习总结》,我认为这部分看我的笔记肯定还不如他的通俗易懂。

    3.HTTP连接管理和HTTP优化

    我们知道HTTP协议直接紧挨着TCP协议,因为TCP为HTTP提供了一条可靠的比特传输通道,从TCP连接的一端填入的字节会从还有一端已原来的顺序、正确地传送出来,让HTTP协议不用考虑传输的细节。能够集中尽力处理应用层的事情。那我们能够这样理解,HTTP传输的性能非常大程度上直接取决于底层TCP通道的性能。

    我们仅仅有更好的理解了TCP的某些性能特点之后,就能够更好的理解HTTP的连接优化特性,这样我们才干够考虑到我们的软件有更高的HTTP性能。以下说说TCP协议对HTTP性能的影响:

    1.HTTP的时延

    在 HTTP 请求的过程中会出现哪些网络时延,并以此開始我们的TCP 性能之旅。图 1 描绘了 HTTP 事务基本的连接、传输以及处理时延。


    这里写图片描写叙述

    与因特网传输请求报文,以及server处理请求报文都须要时间。

    建立 TCP 连接。以及传输请求和响应报文的时间相比。事务处理时间可能是非常短的。除非client或server超载,或正在处理复杂的动态资源,否则 HTTP时延就是由 TCP 网络时延构成的。

    HTTP 事务的时延有以下几种主要原因:

    1. client首先须要依据 URI 确定 Web server的 IP 地址和port号。

      假设近期没有对URI 中的主机名进行訪问,通过 DNS 解析系统将 URI 中的主机名转换成一个 IP地址可能要花费数十秒的时间。

    2. 接下来。client会向server发送一条 TCP 连接请求,并等待server回送一个请求接受应答。

      每条新的 TCP 连接都会有连接建立时延。这个值通常最多仅仅有一两秒钟,但假设有数百个 HTTP 事务的话,这个值会高速地叠加上去。

    3. 一旦连接建立起来了,client就会通过新建立的 TCP 管道来发送 HTTP 请求。数据到达时,Web server会从 TCP 连接中读取请求报文,并对请求进行处理。因特网传输请求报文,以及server处理请求报文都须要时间。

    4. 然后,Web server会回送 HTTP 响应,这也须要花费时间。

    这些 TCP 网络时延的大小取决于硬件速度、网络和server的负载,请求和响应报文的尺寸,以及client和server之间的距离。

    TCP 协议的技术复杂性也会对时延产生巨大的影响。

    2.性能聚集区域

    • 本节其余部分列出了一些会对 HTTP 程序猿产生影响的、最常见的 TCP 相关时延。当中包括:
      1. TCP 连接建立握手;
      2. TCP 慢启动拥塞控制;
      3. 数据聚集的 Nagle 算法;
      4. 用于捎带确认的 TCP 延迟确认算法;
      5. TIME_WAIT 时延和port耗尽。

    以下我们主要说说TCP连接的握手时延、延时确认、TCP慢启动。

    1.TCP连接的握手延时

    建立一条新的 TCP 连接时。甚至是在发送随意数据之前,TCP 软件之间会交换一系列的 IP 分组,对连接的有关參数进行沟通(參见图 2) 。假设连接仅仅用来传送少量数据,这些交换过程就会严重降低 HTTP 的性能。

    这里写图片描写叙述

    TCP 连接握手须要经过以下几个步骤。

    1. 请求新的 TCP 连接时。client要向server发送一个小的 TCP 分组(一般是 40 ~60 个字节) 。这个分组中设置了一个特殊的 SYN 标记,说明这是一个连接请求。

    2. 假设server接受了连接,就会对一些连接參数进行计算,并向client回送一个TCP 分组。这个分组中的 SYN 和 ACK 标记都被置位,说明连接请求已被接受。
    3. 最后。client向server回送一条确认信息,通知它连接已成功建立。现代的 TCP 栈都同意client在这个确认分组中发送数据。

    HTTP 程序猿永远不会看到这些分组——这些分组都由 TCP/IP 软件管理,对其是不可见的。

    HTTP 程序猿看到的仅仅是创建 TCP 连接时存在的时延。

    通常 HTTP 事务都不会交换太多数据,此时。SYN/SYN+ACK 握手会产生一个可測量的时延。

    TCP 连接的 ACK 分组通常都足够大。能够承载整个 HTTP 请求报文4,并且非常多 HTTP server响应报文都能够放入一个 IP 分组中去(比方。响应是包括了装饰性图片的小型 HTML 文件。或者是对浏览器高速缓存请求产生的 304 Not Modified 响应) 。

    最后的结果是,小的 HTTP 事务可能会在 TCP 建立上花费 50%,或很多其它的时间。后面的小节会讨论 HTTP 是怎样通过重用现存连接。来减小这样的 TCP 建立时延所造成的影响的。

    2.确认延时

    因为因特网自身无法确保可靠的分组传输(因特网路由器超负荷的话,能够随意丢弃分组) ,所以 TCP 实现了自己的确认机制来确保数据的成功传输。每一个 TCP 段都有一个序列号和数据完整性校验和。每一个段的接收者收到完善的段时,都会向发送者回送小的确认分组。

    假设发送者没有在指定的窗体时间内收到确认信息,发送者就认为分组已被破坏或损毁,并重发数据。
    因为确认报文非常小,所以 TCP 同意在发往相同方向的输出数据分组中对其进行“捎带” 。TCP 将返回的确认信息与输出的数据分组结合在一起,能够更有效地利用网络。

    为了添加确认报文找到同向传输数据分组的可能性,非常多 TCP 栈都实现了一种“延迟确认”算法。

    延迟确认算法会在一个特定的窗体时间(一般是 100 ~ 200 毫秒)内将输出确认存放在缓冲区中,以寻找能够捎带它的输出数据分组。假设在那个时间段内没有输出数据分组,就将确认信息放在单独的分组中传送。
    可是,HTTP 具有双峰特征的请求 - 应答行为降低了捎带信息的可能。当希望有相反方向回传分组的时候,偏偏没有那么多。

    通常。延迟确认算法会引入相当大的时延。依据所使用操作系统的不同,能够调整或禁止延迟确认算法。

    在对 TCP 栈的不论什么參数进行改动之前,一定要对自己在做什么有清醒的认识。TCP中引入这些算法的目的是防止设计欠佳的应用程序对因特网造成破坏。对 TCP 配置进行的随意改动。都要绝对确保应用程序不会引发这些算法所要避免的问题。

    2.TCP慢启动

    TCP 传输数据的性能还取决于 TCP 连接的使用期(age) 。TCP 连接会随着时间进行自我“调谐” 。起初会限制连接的最大速度。假设数据成功传输,会随着时间的推移提高传输的速度。这样的调谐被称为 TCP 慢启动(slow start) ,用于防止因特网的突然过载和拥塞。

    TCP 慢启动限制了一个 TCP 端点在随意时刻能够传输的分组数。

    简单来说。每成功接收一个分组。发送端就有了发送另外两个分组的权限。

    假设某个 HTTP 事务有大量数据要发送。是不能一次将全部分组都发送出去的。

    必须发送一个分组,等待确认;然后能够发送两个分组,每一个分组都必须被确认。这样就能够发送四个分组了,以此类推。

    这样的方式被称为“打开拥塞窗体” 。

    因为存在这样的拥塞控制特性,所以新连接的传输速度会比已经交换过一定量数据的、“已调谐”连接慢一些。因为已调谐连接要更快一些,所以 HTTP 中有一些能够重用现存连接的工具。

    3.HTTP连接性能优化

    针对TCP传输过程中的报文时延,有一些优化处理办法的办法来提供HTTP的连接性能:

    1.并行连接

    比方:我们的浏览器请求server资源的HTML页面,HTML页面包括非常多文字和多个图片资源,假设我们对文字和图片都一个一个请求,页面载入效果实在太慢。
    眼下主流浏览器的解决的方法是多个线程发起HTTP请求处理,并行的运行多个事务。

    可是,并行连接并非越多越好,并行连接可能能够提高页面的訪问速度,可是并行连接不一定一直都是更快。

    可能还有非常多其它的制约因素。比方:client的网络宽带不足,在低速率的网络环境下,一个HTTP事务可能就已经耗尽了网络的带宽。

    并且,打开大量连接会消耗非常多内存资源,从而引发性自身的性能问题。

    所以,眼下的主流浏览器尽管使用了并行连接,可是他们对并行连接的总数都限制在一个较小的数字

    2.持久连接

    我们的client(App 或者 web浏览器)常常打开到同一个网站的连接。

    比方:一个Web页面上的大部分内嵌图片通常都来自同一个Web网站,并且相当一部分指向其它对象的超链接通常都指向同一个网站。因此,初始化对某个server的HTTP请求的应用程序非常可能会在不久的将来对那台server发起很多其它的请求(比方:获取图片)。这样的性质叫网站本地性。

    因此,HTTP/1.1(以及HTTP/1.0的各个增强版本号)同意HTTP设备在事务处理结束之后将TCP连接保持在打开状态,以便为未来的HTTP请求重用现存的连接。在事务处理结束之后仍然保持在打开状态的TCP连接称为持久连接。非持久连接会在每一个事务结束后关闭。持久连接会在不同事务之间保持打开状态。直到client或者server决定将其关闭为止。

    重用已对目标server打开的空暇持久连接,就能够避开缓慢的连接建立阶段。并且,已经打开的连接还能够避免慢启动的拥塞适应阶段。以便更高速地经行数据的传输。
    关于持久连接的优点。以下引用原著的一幅图来说明:

    这里写图片描写叙述
    从图我们知道,简单的HTTP串行连接上实现4个HTTP事务的时间线与在一条持久连接上实现相同事务所需的时间线进行了比較。

    因为去掉进行连接和关闭连接的开销。所以时间线有所缩短。

    4.HTTP协议连接处理

    client请求时,给 HTTP请求头加入”Connection: Keep-Alive”属性。开启keep-alive机制,通过使用keep-alive机制,能够降低TCP连接建立次数,也意味着能够降低TIME_WAIT状态连接。以此提高性能和提高server的吞吐率(更少的TCP连接意味着更少的系统内核调用)。

    以下说说下HTTP/1.0 和HTTP/1.1 下的keep-Alive的区别:

    HTTP/1.0

    在HTTP/1.0版本号中,并没有官方的标准来规定Keep-Alive怎样工作,因此实际上它是被附加到HTTP/1.0协议上,假设client浏览器支持Keep-Alive。那么就在HTTP请求头中加入一个字段 Connection: Keep-Alive。当server收到附带有Connection: Keep-Alive的请求时。它也会在响应头中加入一个相同的字段来使用Keep-Alive。

    这样一来,client和server之间的HTTP连接就会被保持。不会断开(超过Keep-Alive规定的时间,意外断电等情况除外),当client发送另外一个请求时。就使用这条已经建立的连接。

    HTTP/1.1

    在HTTP/1.1版本号中。官方规定的Keep-Alive使用标准和在HTTP/1.0版本号中有些不同,默认情况下所在HTTP1.1中全部连接都被保持,除非在请求头或响应头中指明要关闭:Connection: Close 。这也就是为什么Connection: Keep-Alive字段再没有意义的原因。

    1.Keep-Alive细节

    说说两点Keep-Alive模式的一些细节,让我们对Kepp-Alive模式有更具体的了解:

    1. Keep-Alive模式下。client怎样推断请求所得到的响应数据已经接收完毕?

    1.使用消息首部字段Conent-Length

    故名思意。Conent-Length表示实体内容长度,client(server)能够依据这个值来推断数据是否接收完毕。

    2.使用消息首部字段Transfer-Encoding(chunk:分块)

    当client向server请求一个静态页面或者一张图片时,server能够非常清楚的知道内容大小。然后通过Content-length消息首部字段告诉client须要接收多少数据。可是假设是动态页面等时。server是不可能预先知道内容大小,这时就能够使用Transfer-Encoding:chunk模式(分块传输)来传输数据了。即假设要一边产生数据,一边发给client。server就须要使用”Transfer-Encoding: chunked”这样的方式来取代Content-Length。

    2. Keep-Alive握手须要client和server一起说的才算吗?

    假设server愿意为下一条请求在连接保持在打开状态。就在对应中包括相同的首部。假设对应中没有Connection:Keep-Alive首部。client就认为server不支持keep-alive。会在发送对应报文之后关闭连接。
    还有当server给client报文包括 Connection:close首部。表示server告诉client要关闭连接。

    2.Keep-Alive选项

    Keep-Alive首部仅仅是请求将连接保持在活跃状态。发出keep-Alive请求之后。client和server并不一定会同意进行keep-alive会话。他们能够在随意时刻关闭空暇的Keep-Alive连接,并可随意显示Keep-Alive连接所处理事务的数量。

    能够用Keep-Alive通用首部中制定的、由逗号分隔的选项来调节Keep-Alive的行为。

    • 參数timeout是在Keep-Alive响应首部发送的。它预计了server希望将连接保持在活跃状态的时间。这并非一个承诺值。
    • 參数max是在Keep-Alive响应首部发送的。它预计了server还希望为多少个事务保持此连接的活跃状态。

      这并非一个承诺值。

    • Keep-Alive首部还可支持随意未经处理的属性。这些属性主要用于诊断和调试。

      语法为name [=value].

    以上部分为本人学习HTTP的报文和连接的笔记记录,关于HTTP与Cookie机制深入理解。推荐大家转到这篇文章《细说Cookie》。

    解析HTTP、 Socket、 WebSocket等几个概念:

    Socket是什么呢?

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层。它是一组接口。就是我们常常说的套接字,在设计模式中。Socket事实上就是一个门面模式。它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

    实际上,传输层的TCP是基于网络层的IP协议的。而应用层的HTTP协议又是基于传输层的TCP协议的,而Socket本身不算是协议,就像上面所说,它仅仅是提供了一个针对TCP或者UDP编程的接口。

    HTTP 协议跟Socket的最大的区别

    HTTP 你不是你要,server怎么知道你要呢,所以,你要跟server说撒(request)。 HTTP是健忘鬼。刚还在问server伸手(request)要东西,要完立即就完了。
    Socket client和服务是双向连接。一次建立连接,除非主动断交,不然就两方记住了。

    举个样例:比方我们实现一个简单的聊天室程序:假设我们用HTTP实现。最大难题HTTP太健忘(无状态特性),请求一次下次就不记得上次干了啥,会话状态非常难保证;并且,我们假设HTTP是单向请求。我们client须要不断跟server轮询请求,是否有人跟我聊天,说了啥。首先做不到实时聊天。并且,轮询还须要考虑资源、流量问题。还有想要实现群聊更是灾难。以上遇到的问题。恰恰是Socket的优点。

    WebSocket又是什么?

    WebSocket protocol 是HTML5一种新的协议,跟HTTP协议基本没有关系,主要是为了兼容现有浏览器的握手规范而已。Websocket是一个持久化的协议。相对于HTTP这样的非持久的协议来说。

    WebSocket 是基于 TCP 协议。HTTP 也是基于 TCP 协议。WebSocket连接要保持还是关闭是由你server应用控制说的算。WebSocket还是一个全双工的协议,支持server端主动给client发送消息。

    HTML5为什么引入WebSocket协议呢?一方面为了解决HTTP协议无状态、无连接、单向请求不优点理,个人认为WebSocket引入非常大一部分就是为了解决client与服务端实时通信。举个样例:假设用HTTP来实现网页的通知消息功能。我们仅仅能用轮询的方式不断向server发送请求来处理,然而HTTP request 的header是非常长的,里面包括的数据可能仅仅是一个非常小的值,这样会占用非常多的带宽和server资源。而WebSocket协议建立后,server就能够主动向client推送消息。

    比方,我们曾经实如今线聊天室的功能的话,会话状态怎么保存。怎么知道对方有没发送聊天信息,群聊怎么处理都是非常难处理的问题,WebSocket协议的出现,实如今线聊天室的功能就简化很多。PS:有一些移动端App实现的实时聊天功能就是用WebSocket协议来通信。

    因此,我们从功能上能够理解,WebSocket更像是Socket功能实现,但实际跟Socket协议没有关系。此处补充下。Socket协议支持TCP和UDP两种方式,而WebSocket仅仅支持TCP。

    转载请注明出处:http://blog.csdn.net/Johnnyz1234/article/details/47859563

  • 相关阅读:
    WLAN 802.11 a/b/g PHY Specification and EDVT Measurement III
    L233
    L232 No methane on Mars
    leetcode 38 Count and Say ---java
    海量字符串查找——bloom filter,c
    leetcode 37 Sudoku Solver java
    mount --bind使用方法
    ECS API
    Linux挂载磁盘
    ECS简述
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7389310.html
Copyright © 2011-2022 走看看