zoukankan      html  css  js  c++  java
  • HTTP rfc是什么及其工作过程

    概念:

    HTTP协议描述的是发送方与接收方的通信协议,通过两方的自觉遵守而存在,HTTP是运行于应用层的协议,基于TCP协议而运作。基本上是客户/服务器对答模式,其中也包括在传输过程中的代理,网关,通道,缓存等都需要遵守这份协议。HTTP所表达的控制以及描述性相关的信息都包含在了HTTP的起始行和首部之中,HTTP被设计成为一种非常容易扩展的协议,因此协议时松散的。头域可以加入需要的头部名和指定的值,尽管有的头部没有加入RFC标准,但是可能成为约定成俗的标准。rfc基本是字段与头部格式的定义,较难理解的部分可能数连接机制与缓存机制。HTTP/1.1支持两种连接机制,一种是非持久连接,第二种是持久连接。基本上默认是使用持久连接,因为这样能够减少建立连接时候的网络延时与CPU消耗。其中服务器与客户端都会假定连接没有关闭,除非对方传来的头文件包含" Connection:close",不然连接将继续保持。客户端,服务器与代理都可以随时结束连接,而他们也应该有一套机制去重新搭建起连接,并保持正确性。每个客户端也只能与一个服务器保持两条连接。代理也只能保持2N条连接,N 为代理的活跃用户数。对于连接的时候,由用户向服务器端发送一个带有"Expect"的信息到服务器端,服务器端如果连接正常则返回一个100 ( continue )的信息到客户端,提示客户端可以继续发送,HTTP对于传输道路上的元素也有一定的要求。也规定了不透明代理可以改变哪些字段,而不能改变哪些字段;HTTP中使用缓存主要有两个作用,一个是在很多情况下可以减少发送包,减少网络IO,使用“过期”机制来处理;第二个是可以减少发送整包的操作,减少带宽需求,使用“验证”机制来处理。“过期”机制(Expiration Model):用于服务器端制定一个“过期时间”,主要有两种计算方式,按优先级顺序,第一种是年龄(Age),第二种是过期时间(Expiration)。对于第一种,服务器会提供一个年龄字段(Age)与一个有效年龄(max-age),而年龄的计算,则是采用服务器生成时的初始年龄再加上从服务器生成至缓存的时间。如果有Age 这个字段的存在,则说明这个消息不是第一手的,中间有缓存的存在。验证机制(Validation Model ) :采用这种机制的时候,缓存先向服务器验证当前的缓存条目是否最新的,则收到304的提示表示 Not Modified,条目是最新的。否则则会收到服务器返回的新缓存条目。而进行验证的时候,可以使用两个标准,一个是使用服务器在原条目上的"Last-Modified",使用条件GET(If-Modified-Since OR If-Not-Modified-Since)去查询。第二个是使用服务器为每个条目生成的"Entity Tag",这个Tag如何生成完成由服务器去决定,因此也衍生出两种验证策略,一种是强验证,即如果一个条目发生了改变之后"Entity Tag"也马上变化的,第二种是使用弱验证,即条目变化了"Entity Tag"仍然保持不变,相对验证条件更弱。而对于是使用强验证还是弱验证则是取决于服务器端了。

    工作流程:

    如用客户端浏览器请求这个页面:http://localhost.com:8080/index.htm 从中分解出协议名、主机名、端口、对象路径等部分,对于我们的这个地址,解析得到的结果如下: 协议名:http 主机名:localhost.com 端口:8080 对象路径:/index.htm 在这一步,需要域名系统DNS解析域名localhost.com,得主机的IP地址。

    把以上部分结合本机自己的信息,封装成一个HTTP请求数据包
    在HTTP工作开始之前,客户机(Web浏览器)首先要通过网络与服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。这里是8080端口
    建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可内容。
    服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
    实体消息是服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据
    一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码Connection:keep-alive。TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
    HTTP1.0 使用的是非持久连接,主要缺点是客户端必须为每一个待请求的对象建立并维护一个新的连接,即每请求一个文档就要有两倍RTT 的开销。因为同一个页面可能存在多个对象,所以非持久连接可能使一个页面的下载变得十分缓慢,而且这种短连接增加了网络传输的负担。HTTP1.1 使用持久连接keepalive,所谓持久连接,就是服务器在发送响应后仍然在一段时间内保持这条连接,允许在同一个连接中存在多次数据请求和响应,即在持久连接情况下,服务器在发送完响应后并不关闭TCP 连接,而客户端可以通过这个连接继续请求其他对象。
    HTTP/1.0 每次请求都需要建立新的TCP连接,连接不能复用。HTTP/1.1 新的请求可以在上次请求建立的TCP连接之上发送,连接可以复用。优点是减少重复进行TCP三次握手的开销,提高效率。
    第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
    第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
    第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
    TCP三次握手.png
    TCP三次握手.png
    四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:
    TCP的四次挥手.png
    TCP的四次挥手.png
    由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
    第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
    第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
    第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
    这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送
  • 相关阅读:
    js复制文字到剪切板
    js推送网页到扩展屏上
    数据库自增ID用完了会怎么样?
    使用@nuxtjs/sitemap给项目添加sitemap(网站地图)
    js实现视频截图,视频批量截图,canvas实现
    javascript深入参数传递
    基于JQ使用原生js构造一个自动回复随机消息的机器人
    把nodejs程序打包成可执行文件
    如何巧妙使用some函数来优化性能
    Eggjs 设置跨域请求 指定地址跨域 nodejs
  • 原文地址:https://www.cnblogs.com/vision-xixi/p/10449680.html
Copyright © 2011-2022 走看看