趣谈网络协议笔记-二(第十四讲)

趣谈网络协议笔记-二(第十四讲)

HTTP协议:看个新闻原来这么麻烦


前言

还是从前言写起吧,虽然现在还有两分钟就到明天了,但是还是打算奋斗一下。
人们都说,22天左右可以形成一个习惯,现如今,我持续写这个已经过半了,再坚持写剩下的一半,那么这个所谓的优秀的好习惯就形成了。啊,明天已到= =
初闻不知曲中意,再听已是曲中人。
人真的是会随着年纪的渐长,会渐渐地将自己的一些事情回忆起来,有些让人快乐和自豪,有些却当人后悔。
我时常提醒自己,我的时间已经不多了。既没有时间让我去再为过去所达成的成就沾沾自喜,也没有时间让我再去为过去的胡作非为而感到后悔。
曹操不就说过吗,“宁让我负天下人,休让天下人负我”!何等文采,何等疯狂,何等魄力!
先这样吧= =,想起来今天还要赶一份ppt,睡太晚估计明天就起不来了!


引用

  • GET和POST两种基本请求方法的区别 - yinrw - 博客园
  • HTTP1.0、HTTP1.1 和 HTTP2.0 的区别 - zhangyfr - 博客园

正文

趣谈网络协议笔记-二(第十四讲)_第1张图片

这个是HTTP的传输数据时的基本结构,说真的,我之前一直很好奇一件事情,就是GET和POST两种基本请求方法的区别 - yinrw - 博客园这篇博客中所说的为什么GET请求只需要一个TCP包就能完成,但是POST包必须要两个以上,这个问题在我脑中思考了一整天吧,虽然不是一直思考,但是基本上来说是潜意识中一直存在着。
那么到底为什么呢?
首先,我认为,将具体需要传输的实体当成http协议的一部分其实是有一些歧义的。http是什么意思?hypertext transport protocol,超文本传输协议。也就是说http协议存在的目的是对实体传输的方式进行进一步的描述,比如说,我需要告诉你,我将要传递给你的文本内容是json格式的啊,我想要请求的文件在目的地的具体位置啊等等。
[image:504CDCEE-A779-4B3F-B083-7B23FF32333C-305-00000BA2CEAF2BC0/374E46F9-B809-4E96-9C9C-A40157D78D4A.png]

通过WireShark的抓包结果就能很明显地看出来,在刘超的叙述中的所谓的实体,其实不太应该被归于http层。按照我个人的理解,无论是7层还是4层的网络结构定义,终归会被归类于协议,何为协议,即你我能接受的统一一套对于事务的描述方式,注意,仅仅是方式而已,不应该包含具体的实体。就好比,我如果仅仅使用socket进行传输,那么是不是意味着tcp或者udp协议也有实体了。所以,按照我个人的理解,既然要分层,就是为了更加充分的解耦,协议模型的每层架构其实都有一个普遍的特点,那就是上层其实并不会知道下层的任何信息,但是下层其实很清楚其上一层的识别信息,基于此来实现解耦和分层的目的。就比如说mac头会记录着ip信息,便于上层进行识别。ip层会记录着端口号,便于传输层进行识别等等。所以在前面的章节中,有提到过,下层可以脱离上层而存在,但是上层不能脱离下层而存在,因为上层是通过下层的介绍才能获取到外部传输来的数据。
按照这个思路(将http协议视为对于传输方法进行描述的角度)来看,“为什么GET只需要一个TCP包就行了,而POST不行“的这个问题就很好解答了。因为我不知道我所希望的方式你到底认不认同。HTTP包的请求行中包含了请求的方式GET,请求的URL,以及请求的HTTP的版本,然后首部中基于请求头会进行进一步的描述。这里就有一些问题了,要是接收方不支持你的版本,那不是很尴尬。所以,当使用POST数据时,第一个包用于确认我的希望用于传输的版本你支不支持,确保你支持了,我再传第二个包用以传输实体。但是GET并不带实体啊= =,我所有的请求参数都放在包头了,通过第一个包就同时把请求和确认两个操作同时完成了。
趣谈网络协议笔记-二(第十四讲)_第2张图片

然后接下来就是这幅图了,所谓的高并发的网络架构图。无论在什么年代,资源都是稀缺的,不是可利用的资源完全没有增长,而是人类的欲望增长的远比资源增长的速度快。DNS和CDN会在后面的章节中进行描述。这幅图给我的最好的启发就是所谓的分类的思想,对于那些变化频繁的数据和变化迟缓的数据的区别对待。

然后就是HTTP1.0,1.1和2.0版本之间的迭代,以及QUIC为什么会出现,注意,我写这个笔记系列的作用仅仅是进行整体的梳理,很多细节其实都先暂时性忽略了。
趣谈网络协议笔记-二(第十四讲)_第3张图片

HTTP的迭代和QUIC的出现的目的大体还是为了能够让服务器能够更多更快地响应请求。首先是1.0版本之前,每次进行HTTP请求都是需要通过TCP协议重新建立起连接,建立连接的过程是一种微妙的试探性过程,所以一般比较慢。
为了解决这个问题,HTTP1.1版本默认就将连接设置成可复用的,这样一来,当进行第二次,第三次乃至更多次请求时,就不用重复进行建立连接的操作,时间也就省下来了。但是多个请求使用的是同一个复用的接口,所以根据TCP协议,如果前面的请求没有结束之前,是没有办法获取到后续请求的结果的。当然,可以通过pipeline的方式来达到并发的方式,也就是通过创建多条连接的方式,但是这样其实对于接口是存在着一些浪费的,毕竟服务器能同时维护的接口数量是有限的。
趣谈网络协议笔记-二(第十四讲)_第4张图片

为了解决这个问题,2.0版本尝试将复用进行到极致,对于客户端和服务器之间,仅仅维护两条连接,分别用于传输head,和实体。用一条连接用于专门传输实体这一点其实不难理解,因为1.1的不能达成并发响应的原因就是因为TCP固执的执着于顺序,那么我将多个实体混在一起不就可以达成并发的要求了。既然混在一起了,那么就需要一些标识来互相区别,就需要通过一条专门传输head的连接来达成目的了。
趣谈网络协议笔记-二(第十四讲)_第5张图片

但是TCP协议为了达成他所追求的可靠性,其在一些地方做出了很大的权衡。趣谈网络协议笔记-二(第十四讲)_第6张图片

第一,发送方重发往往有两个依据,超时时间和服务器方的再发送请求。超时时间是基于已经返回的包的请求返回时间的取样结果来计算的。但是很可惜,这个时间有可能不准,因为在重发的情况下,你不知道你所收到的应答包是针对你发的哪个包的。
趣谈网络协议笔记-二(第十四讲)_第7张图片

第二,就是对于窗口大小的错误估计,会导致客户端过于乐观地估计服务器端的接收能力,从而将发送流量设定在过高的水平。

这也是为什么QUIC会出现的原因,这个协议就是google为了取代HTTP协议而存在的,不过据说也有一些劣势,这个等到后面再去研究吧。这里再去讲解就会让篇幅变得过于冗长了。


你可能感兴趣的:(趣谈网络协议)