计算机基础知识

基础是最重要的

Posted by shmily on August 26, 2019

计算机网络知识总结

一、OSI与TCP/IP各层的结构和功能,都有哪些协议?

1.1 应用层

应用层的任务是通过应用进程间的交互来完成特定网络应用,应用层协议定义的是应用进程(进程是主机中正在运行的程序)间的通信和交互的规则,对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如域名系统DNS,支持邮件的SMTP,支持万维网的HTTP协议,我们应该把应用层交互的数据单元称为报文

域名系统

域名系统(Domain Name System)缩写为DNS,被翻译为域名是因为因特网的一项核心业务,他可以将域名和IP地址相互映射的一个分布式数据库,能够使人们更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串

【百度百科】例如一个公司的web网站可以看做是它在网上的门户,而域名就相当于其门牌地址,通常域名都使用该公司的名称或简称。例如上面提到的微软公司的域名,类似的还有IBM公司的域名等等

【HTTP协议】 超文本传输协议(Http HyperText Transfer Protocol)是互联网上应用最为广泛的一种协议,所有的www(万维网)文件都必须遵守这个标准,设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法

1.2 运输层(传输层)

传输层的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。应用进程利用该服务传送应用层报文。“通用的”是指并不针对某一个特定的网络应用,而是多种应用可以使用同一个运输层服务。由于一台主机可以同时运行多个线程,因此运输层有复用分用的功能。所谓复用就是指多个应用层进程可以用时使用下面运输层的服务,分用和复用相反,是运输层把收到的信息分别交付上面应用层中的相应进程。

传输层主要由以下两种协议:

1.传输控制协议(TCP Transmission Control Protocol)—提供面向链接的,可靠的数据传输服务

2.用户数据协议(UDP User Datagram Protocol)—提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)

TCP UDP协议的区别

UDP是不具有可靠性的数据报协议。UPD在传送数据之前不需要先建立连接,远地主机在收到UDP报文后,不需要给出任何确认,虽然UDP不提供可靠交付,但是在某些情况下UDP确实是一种最有效的工作方式(一般用于即时通信)比如:QQ语音,QQ视频,直播等等 UDP是一种将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制,即使是出现网络拥堵的情况下,UDP也无法进行流量控制等避免网络拥堵的行为。此外,传输途中即使出现丢包,UDP也不负责重发,甚至当出现包的到达顺序乱掉的时候也没有纠正的功能,如果需要这些细节控制,那么不得不交由采用UDP的应用程序去处理,经常用于以下场景:

  • 包总量较少的通信(DNS,SNMP等)
  • 视频,音频等多媒体通信(即时通信)
  • 限定于LAN等特定网络中的应用通信
  • 广播通信(广播,多播)

TCP提供面向连接的,可靠的的流协议(流就是指不间断的数据结构)。在传送数据之前必须先建立连接,数据传送结束后要释放连接。TCP不提供广播或者多播服务,由于TCP要提供可靠的,面向链接的传输服务(TCP的可靠体现在TCP在传送数据之前,会有三次握手来建立链接,而且在数据传递时,有确认,窗口,重传,拥塞控制机制,在数据传完之后,会断开链接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及链接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP一般用于文件传输,发送和接收邮件,远程登录等场景。

HTTP通信必须使用TCP,所以TCP的80端口被HTTP使用,因此UDP的80端口并没有投入使用

1.3 网络层

在计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点,确保数据及时传送。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在TCP/IP体系结构中,由于网络层使用IP协议,因此分组也叫做IP数据报,简称数据报

这里要注意:不要把运输层的“用户数据报UDP”和网络层的“IP数据报”弄混。另外,无论是哪一层的数据单元,都可以笼统的用分组来表示。

这里强调指出,网络层中的“网络”二字已经不是我们通常谈到的具体网络,而是指计算机网络体系中第三层名称。

互联网是由大量的异构和网络通过路由器相互连接起来的。互联网使用的网络层协议是无连接的网际协议和许多路由选择协议,因此互联网的网络层也叫做网际层IP层

1.4 数据链路层

数据链路层通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。在两个相邻节点之间传输数据时,数据链路层将网络层交下来IP数据报组装成帧,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)

在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提出数据部分,上交给网络层。 控制信息还使接收端能够检测到所收到的帧中有误差错。如果发现差错,数据链路层就简单地丢弃这个出了差错的帧,以避免继续在网络中传送下去白白浪费网络资源。如果需要改正数据在链路层传输时出现差错(这就是说,数据链路层不仅要检错,而且还要纠错),那么就要采用可靠性传输协议来纠正出现的差错。这种方法会使链路层的协议复杂些。

1.5 物理层

在物理层上所传送的数据单位是比特。 物理层(physical layer)的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。 使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。

在互联网使用的各种协中最重要和最著名的就是 TCP/IP 两个协议。现在人们经常提到的TCP/IP并不一定单指TCP和IP这两个具体的协议,而往往表示互联网所使用的整个TCP/IP协议族。

二、TCP三次握手和四次挥手(重点!!!)

###2.1 TCP三次握手

简单示意图:

  • 客户端-发送带有SYN标志的数据包———-一次握手—-服务端
  • 服务端-发送带有SYN/ACK标志的数据包——二次握手—-客户端
  • 客户端-发送带有ACK标志的数据包———-三次握手—-服务端

2.2 为什么要三次握手

三次握手的目的是建立可靠的通信信道,说道通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。

第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常

第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常

第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常

所以三次握手就能确认双发收发功能都正常,缺一不可。

2.3为什么要传回SYN

接收端传回发送端所发送的SYN是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。

SYN 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常
的 TCP 网络连接时,客户机首先发出一个SYN消息,服务器使用SYN-ACK
应答表示接收到了这个消息,最后客户机再以ACK消息响应。这样在客户机和服务器之	间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。

Acknowledgement[汉译: 确认字符 ,在数据通信传输中,接收站发给发送站的一种传输控制字符。它表示 确认发来的数据已经接受无误。 ]

2.4传了SYN,为什么还要传ACK

双发通信无误必须是两者相互发信息都无误。传SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要ACK信号来进行验证

断开一个TCP需要连接则需要“四次挥手”

  • 客户端-发送一个FIN,用来关闭客户端到服务器的数据传送
  • 服务端-收到这个FIN,它发回一个ACK,确认序号为收到的序号加1.和SYN一样,一个FIN将占用一个序号
  • 服务端-关闭与客户端的链接,发送一个FIN给客户端
  • 客户端-发回ACK报文回收,并将确认序号设置为收到序号加1

2.5 为什么要四次挥手

任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。

举个例子:A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束。

上面讲的比较概括,推荐一篇讲的比较细致的文章:【 https://blog.csdn.net/qzcsu/article/details/72861891】

2.6 为什么客户端最后还要等2MSL

MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。

第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

2.8 为什么建立链接是三次握手,关闭连接却是四次握手呢?

建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。 而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

四、TCP协议如何保证可靠传输

1、应用数据被分割成 TCP 认为最适合发送的数据块。

2、TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。

3、校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。

4、TCP 的接收端会丢弃重复的数据。

5、流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)

6、拥塞控制: 当网络拥塞时,减少数据的发送。

7、ARQ协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。

8、超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

4.1 ARQ协议

自动重传请求(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时重传机制,不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ包括停止等待AQR协议和连续ARQ协议。

停止等待ARQ协议

  • 停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组;
  • 在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认;

优点: 简单

缺点: 信道利用率低,等待时间长

1) 无差错情况:

发送方发送分组,接收方在规定时间内收到,并且回复确认.发送方再次发送。

2) 出现差错情况(超时重传):

停止等待协议中超时重传是指只要超过一段时间仍然没有收到确认,就重传前面发送过的分组(认为刚才发送过的分组丢失了)。因此每发送完一个分组需要设置一个超时计时器,其重传时间应比数据在分组传输的平均往返时间更长一些。这种自动重传方式常称为 自动重传请求 ARQ 。另外在停止等待协议中若收到重复分组,就丢弃该分组,但同时还要发送确认。连续 ARQ 协议 可提高信道利用率。发送维持一个发送窗口,凡位于发送窗口内的分组可连续发送出去,而不需要等待对方确认。接收方一般采用累积确认,对按序到达的最后一个分组发送确认,表明到这个分组位置的所有分组都已经正确收到了。

3) 确认丢失和确认迟到

  • 确认丢失:确认消息在传输过程丢失 当A发送M1消息,B收到后,B向A发送了一个M1确认消息,但却在传输过程中丢失。而A并不知道,在超时计时过后,A重传M1消息,B再次收到该消息后采取以下两点措施:

丢弃这个重复的M1消息,不向上层交付。 向A发送确认消息。(不会认为已经发送过了,就不再发送。A能重传,就证明B的确认消息丢失)。

  • 确认迟到 :确认消息在传输过程中迟到 A发送M1消息,B收到并发送确认。在超时时间内没有收到确认消息,A重传M1消息,B仍然收到并继续发送确认消息(B收到了2份M1)。此时A收到了B第二次发送的确认消息。接着发送其他数据。过了一会,A收到了B第一次发送的对M1的确认消息(A也收到了2份确认消息)。处理如下:

A收到重复的确认后,直接丢弃。 B收到重复的M1后,也直接丢弃重复的M1。 连续ARQ协议

连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。

  • 优点: 信道利用率高,容易实现,即使确认丢失,也不必重传。

  • 缺点: 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5条 消息,中间第三条丢失(3号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退 N),表示需要退回来重传已经发送过的 N 个消息。

4.2 滑动窗口

TCP用滑动窗口实现流量控制。流量控制就是为了控制发送方发送速率,保证接收方来得及接收。接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方发送速率。将窗口字段设置为0,则发送方不能发送数据

4.3 拥塞控制

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

为了进行拥塞控制,TCP 发送方要维持一个 拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。

TCP的拥塞控制采用了四种算法,即 慢开始 、 拥塞避免 、快重传 和 快恢复。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM),以减少网络拥塞的发生。

  • 慢开始(慢启动): 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd初始值为1,每经过一个传播轮次,cwnd加倍。

  • 拥塞避免: 拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送放的cwnd加1.
  • 快重传与快恢复: 在 TCP/IP 中,快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了 FRR,就不会因为重传时要求的暂停被耽误。  当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。

五、在浏览器中输入URL地址 发生了什么

总体来说分为以下几个过程:

DNS解析
TCP连接
发送HTTP请求
服务器处理请求并返回HTTP报文
浏览器解析渲染页面
连接结束

具体过程:

  • DNS解析:DNS解析的过程就是寻找那台机器上有你需要的资源,当你在浏览器中输入一个地址时,例如www.baidu.com,其实不是百度网站真正的意义。互联网上的每一台计算机的唯一标识就是它的IP地址,但是IP地址并不方便记忆。用户更喜欢用方便的记忆网址去寻找互联网上的其他计算机,也就是上面提到的百度网址,所以互联网设计者需要在用户的方便性与可用性方面做一个权衡,这个权衡就是一个网址到IP地址的转换,这个过程就是DNS解析。它实际上充当了一个翻译的角色,实现了网址到IP地址的转换。网址到IP地址转换的过程是如何进行的?
  • 解析过程:DNS解析是一个递归查询的过程

上述图片是查找www.google.com的IP地址过程。首先在本地域名服务器中查询IP地址,如果没有找到的情况下,本地域名服务器会向根域名服务器发送一个请求,如果根域名服务器也不存在该域名时,本地域名会向com顶级域名服务器发送一个请求,依次类推下去。直到最后本地域名服务器得到google的IP地址并把它缓存到本地,供下次查询使用。从上述过程中,可以看出网址的解析是一个从右向左的过程: com -> google.com -> www.google.com。但是你是否发现少了点什么,根域名服务器的解析过程呢?事实上,真正的网址是www.google.com.,并不是我多打了一个.,这个.对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.,既然是默认情况下,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上,所有网址真正的解析过程为: . -> .com -> google.com. -> www.google.com.。

DNS优化

了解了DNS的过程,可以为我们带来哪些?上文中请求到google的IP地址时,经历了8个步骤,这个过程中存在多个请求(同时存在UDP和TCP请求,为什么有两种请求方式,请自行查找)。如果每次都经过这么多步骤,是否太耗时间?如何减少该过程的步骤呢?那就是DNS缓存。

 **DNS在进行区域传输的时候使用TCP协议,其它时候则使用UDP协议**; 
DNS的规范规定了2种类型的DNS服务器,一个叫主DNS服务器,一个叫辅助DNS服务
器。在一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息,而
辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。当一个辅助DNS服
务器启动时,它需要与主DNS服务器通信,并加载数据信息,这就叫做区传送(zone
transfer)

首先了解一下TCP与UDP传送字节的长度限制

UDP报文的最大长度为512字节,而TCP则允许报文长度超过512字节。当DNS查询超过512字节时,协议的TC标志出现删除标志,这时则使用TCP发送。通常传统的UDP报文一般不会大于512字节。

1.区域传送时使用TCP,主要有以下两点考虑

1.1 辅域名服务器会定时(一般时3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,则会执行一次区域传送,进行数据同步。区域传送将使用TCP而不是UDP,因为数据同步传送的数据量比一个请求和应答的数据量要多得多。

2.1 TCP是一种可靠的连接,保证了数据的准确性。

2.域名解析时使用UDP协议

客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。虽然从理论上说,客户端也可以指定向DNS服务器查询的时候使用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。

DNS缓存 DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。

在你的chrome浏览器中输入:chrome://dns/,你可以看到chrome浏览器的DNS缓存。

系统缓存主要存在/etc/hosts(Linux系统)中:

DNS负载均衡

不知道大家有没有思考过一个问题: DNS返回的IP地址是否每次都一样?如果每次都一样是否说明你请求的资源都位于同一台机器上面,那么这台机器需要多高的性能和储存才能满足亿万请求呢?其实真实的互联网世界背后存在成千上百台服务器,大型的网站甚至更多。但是在用户的眼中,它需要的只是处理他的请求,哪台机器处理请求并不重要。DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡,又叫做DNS重定向。大家耳熟能详的CDN(Content Delivery Network)就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。

TCP连接

HTTP协议是使用TCP作为其传输层协议的,当TCP出现瓶颈时,HTTP也会受到影响。但由于TCP优化(就是流量控制、慢启动、拥塞避免,如何调整[rwnd]到一个合理值)

HTTPS协议 我不知道把HTTPS放在这个部分是否合适,但是放在这里好像又说的过去。HTTP报文是包裹在TCP报文中发送的,服务器端收到TCP报文时会解包提取出HTTP报文。但是这个过程中存在一定的风险,HTTP报文是明文,如果中间被截取的话会存在一些信息泄露的风险。那么在进入TCP报文之前对HTTP做一次加密就可以解决这个问题了。HTTPS协议的本质就是HTTP + SSL(or TLS)。在HTTP报文进入TCP报文之前,先使用SSL对HTTP报文进行加密。从网络的层级结构看它位于HTTP协议与TCP协议之间。

HTTPS

HTTPS过程 HTTPS在传输数据之前需要客户端与服务器进行一个握手(TLS/SSL握手),在握手过程中将确立双方加密传输数据的密码信息。TLS/SSL使用了非对称加密,对称加密以及hash等。具体过程请参考经典的阮一峰先生的博客TLS/SSL握手过程。 HTTPS相比于HTTP,虽然提供了安全保证,但是势必会带来一些时间上的损耗,如握手和加密等过程,是否使用HTTPS需要根据具体情况在安全和性能方面做出权衡。

HTTP请求

其实这部分又可以称为前端工程师眼中的HTTP,它主要发生在客户端。发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口(HTTP协议80/8080, HTTPS协议443)。HTTP请求报文是由三部分组成: 请求行, 请求报头和请求正文。

请求行 格式如下:

Method Request-URL HTTP-Version CRLF

eg: GET index.html HTTP/1.1

常用的方法有: GET, POST, PUT, DELETE, OPTIONS, HEAD。

TODO:

GET和POST有什么区别?

请求报头

请求报头允许客户端向服务器传递请求的附加信息和客户端自身的信息。 PS: 客户端不一定特指浏览器,有时候也可使用Linux下的CURL命令以及HTTP客户端测试工具等。 常见的请求报头有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等。

HTTP分析

上图是使用Chrome开发者工具截取的对百度的HTTP请求以及响应报文,从图中可以看出,请求报头中使用了Accept, Accept-Encoding, Accept-Language, Cache-Control, Connection, Cookie等字段。Accept用于指定客户端用于接受哪些类型的信息,Accept-Encoding与Accept类似,它用于指定接受的编码方式。Connection设置为Keep-alive用于告诉客户端本次HTTP请求结束之后并不需要关闭TCP连接,这样可以使下次HTTP请求使用相同的TCP通道,节省TCP连接建立的时间。

请求正文 当使用POST, PUT等方法时,通常需要客户端向服务器传递数据。这些数据就储存在请求正文中。在请求包头中有一些与请求正文相关的信息,例如: 现在的Web应用通常采用Rest架构,请求的数据格式一般为json。这时就需要设置Content-Type: application/json。

服务器处理请求并返回HTTP报文 自然而然这部分对应的就是后端工程师眼中的HTTP。后端从在固定的端口接收到TCP报文开始,这一部分对应于编程语言中的socket。它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般是由Web服务器去进行,我使用过的Web服务器有Tomcat, Jetty和Netty等等。

HTTP响应报文也是由三部分组成: 状态码, 响应报头和响应报文。

状态码 状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:

  • 1xx:指示信息–表示请求已接收,继续处理。

  • 2xx:成功–表示请求已被成功接收、理解、接受。

  • 3xx:重定向–要完成请求必须进行更进一步的操作。

  • 4xx:客户端错误–请求有语法错误或请求无法实现。

  • 5xx:服务器端错误–服务器未能实现合法的请求。

平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分别表示什么请自行查找)。

TODO:

  • 301和302有什么区别?

  • HTTP缓存

该图是本公司对状态码的一个总结,绘制而成的status code map,请大家参考。

响应报头 常见的响应报头字段有: Server, Connection…。

响应报文 服务器返回给浏览器的文本信息,通常HTML, CSS, JS, 图片等文件就放在这一部分。

浏览器解析渲染页面

浏览器在收到HTML,CSS,JS文件后,它是如何把页面呈现到屏幕上的?下图对应的就是WebKit渲染的过程。

浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)。DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色,字体,等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。

Event loop

JS的解析是由浏览器中的JS解析引擎完成的。JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。但是又存在某些任务比较耗时,如IO读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。JS的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务。所有的同步任务在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫做事件循环(Event loop)。

浏览器在解析过程中,如果遇到请求外部资源时,如图像,iconfont,JS等。浏览器将重复1-6过程下载该资源。请求过程是异步的,并不会影响HTML文档进行加载,但是当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等待解析执行完毕,才会继续HTML的渲染过程。原因是因为JS有可能修改DOM结构,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因。CSS文件的加载不影响JS文件的加载,但是却影响JS文件的执行。JS代码执行前浏览器必须保证CSS文件已经下载并加载完毕。

Web优化

上面部分主要介绍了一次完整的请求对应的过程,了解该过程的目的无非就是为了Web优化。在谈到Web优化之前,我们回到一个更原始的问题,Web前端的本质是什么。我的理解是: 将信息快速并友好的展示给用户并能够与用户进行交互。快速的意思就是在尽可能短的时间内完成页面的加载,试想一下当你在淘宝购买东西的时候,淘宝页面加载了10几秒才显示出物品,这个时候你还有心情去购买吗?怎么快速的完成页面的加载呢?优雅的学院派雅虎给出了常用的一些手段,也就是我们熟悉的雅虎34条军规。这34军规实际上就是围绕请求过程进行的一些优化方式。

如何尽快的加载资源?答案就是能不从网络中加载的资源就不从网络中加载,当我们合理使用缓存,将资源放在浏览器端,这是最快的方式。如果资源必须从网络中加载,则要考虑缩短连接时间,即DNS优化部分;减少响应内容大小,即对内容进行压缩。另一方面,如果加载的资源数比较少的话,也可以快速的响应用户。当资源到达浏览器之后,浏览器开始进行解析渲染,浏览器中最耗时的部分就是reflow,所以围绕这一部分就是考虑如何减少reflow的次数。

六、状态码

七、各种协议之间的关系

八、HTTP长连接,短连接

在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协议的长连接和短连接。

九 HTTP是不保存状态的协议,如何保存用户状态?

HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们保存用户状态呢?Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个Session)。

在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库redis保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢?大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪。

Cookie 被禁用怎么办?

最常用的就是利用 URL 重写把 Session ID 直接附加在URL路径的后面。

HTTP是无状态协议

十 Cookie的作用是什么?和Session有什么区别?

Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。

Cookie 一般用来保存用户信息 比如①我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;②一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③登录一次网站后访问网站其他页面不需要重新登录。Session 的主要作用就是通过服务端记录用户的状态。 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。

Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。

Cookie 存储在客户端中,而Session存储在服务器上,相对来说 Session 安全性更高。如果使用 Cookie 的一些敏感信息不要写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。

十一 HTTP 1.0和HTTP 1.1的主要区别是什么?

这部分回答引用这篇文章 https://mp.weixin.qq.com/s/GICbiyJpINrHZ41u_4zT-A? 的一些内容。

HTTP1.0最早在网页中使用是在1996年,那个时候只是使用一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。 主要区别主要体现在:

  • 长连接 : 在HTTP/1.0中,默认使用的是短连接,也就是说每次请求都要重新建立一次连接。HTTP 是基于TCP/IP协议的,每一次建立或者断开连接都需要三次握手四次挥手的开销,如果每次请求都要这样的话,开销会比较大。因此最好能维持一个长连接,可以用个长连接来发多个请求。HTTP 1.1起,默认使用长连接 ,默认开启Connection: keep-alive。 HTTP/1.1的持续连接有非流水线方式和流水线方式 。流水线方式是客户在收到HTTP的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是客户在收到前一个响应后才能发送下一个请求。 错误状态响应码 :在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。

  • 缓存处理 :在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

  • 带宽优化及网络连接的使用 :HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。

    十二 URI和URL的区别是什么?

URI(Uniform Resource Identifier) 是同一资源标志符,可以唯一标识一个资源。

URL(Uniform Resource Location) 是同一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。

URI的作用像身份证号一样,URL的作用更像家庭住址一样。URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。

十三 HTTP 和 HTTPS 的区别?

端口 :HTTP的URL由“http://”起始且默认使用端口80,而HTTPS的URL由“https://”起始且默认使用端口443。

安全性和资源消耗: HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。

对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等;

非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。