衍生问题2:应用层有哪些协议,哪些是TCP,哪些是UDP?
基于TCP的有FTP、SMTP、HTTP、SSH等
基于UDP的应用层协议:DNS、TFTP(简单文件传输协议)、SNMP:简单网络管理协议
第一次握手:客户端发送一个带SYN的TCP报文到服务器,表示客户端想要和服务器端建立连接。
第二次握手:服务器端接收到客户端的请求,返回客户端报文,这个报文带有SYN和ACK确认标示,访问客户端是否准备好。
第三次握手:客户端再次响应服务端一个ACK确认,表示我已经准备好了。
过程理解:
第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
四次挥手:
第一次挥手:TCP发送一个FIN(结束),用来关闭客户端到服务器端的连接。
第二次挥手:服务器端收到这个FIN后发回一个ACK确认标示,确认收到。
第三次挥手:服务器端发送一个FIN到客户端,服务器端关闭客户端的连接。
第四次挥手:客户端发送ACK报文确认,这样关闭完成。
过程理解:
1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
答案:
1.第一次挥手,客户端进程发出连接释放报文,并且停止发送数据。此时,客户端进入FIN-WAIT-1(终止等待1)状态。
2.第二次挥手,服务器收到连接释放报文,发出确认报文,ACK=1,此时服务端就进入了CLOSE-WAIT(关闭等待)状态。服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
3.第三次挥手,服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
4.第四次挥手,客户端收到服务器的连接释放报文后,发出确认报文ACK=1,此时客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
衍生问题1:你刚刚体到了ACK,能不能说下这个ACK?
详细看:https://blog.csdn.net/woshifennu1234/article/details/78349302
在TCP中,当发送端的数据到达接受主机时,接收端主机会返回一个已收到消息的通知。这个消息叫确认应答(也就是ACK)。TCP通过ACK来实现可靠的数据传输,ACK是对接收到的数据的最高序列号的确认,并向发送端返回一个下次接收时期望的TCP数据包的序列号。
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
答案:假设网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。
3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机A和B之间的通信,假定B给A发送一个连接请求分组,A收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,A认为连接已经成功地建立了,可以开始发送数据分组。可是,B在A的应答分组在传输中被丢失的情况下,将不知道A是否已准备好,不知道A建立什么样的序列号,B甚至怀疑A是否收到自己的连接请求分组。在这种情况下,B认为连接还未建立成功,将忽略A发来的任何数据分组,只等待连接确认应答分组。而A在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。
TCP设有一个保活计时器。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
UDP(User Data Protocol,用户数据报协议)TCP(Transmission Control Protocol,传输控制协议)
TCP的优点: 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。 TCP的缺点: 慢,效率低,占用系统资源高,易被攻击. TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
UDP的优点: 快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击…… UDP的缺点: 不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。 基于上面的优缺点,那么: 什么时候应该使用TCP: 当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。 在日常生活中,常见使用TCP协议的应用如下: 浏览器,用的HTTP FlashFXP,用的FTP Outlook,用的POP、SMTP Putty,用的Telnet、SSH QQ文件传输 ………… 什么时候应该使用UDP: 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下: QQ语音 QQ视频 TFTP ……
TCP与UDP基本区别
1.基于连接与无连接;
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式 ;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
什么时候使用TCP什么时候使用UDP?
当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方的时候。 在日常生活中,常见使用TCP协议的应用如下: 浏览器,用的HTTP FlashFXP,用的FTP Outlook,用的POP、SMTP Putty,用的Telnet、SSH QQ文件传输 ………… 什么时候应该使用UDP: 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下: QQ语音 QQ视频 。
UDP应用场景:
1.面向数据报方式
2.网络数据大多为短消息
3.拥有大量Client
4.对数据安全性无特殊要求
5.网络负担非常重,但对响应速度要求高
以下的问题可以看《图解TCP/IP》p203-p215
衍生问题1:讲讲TCP的窗口控制?
TCP以一个数据段为单位,每发一个段进行一次确认应答的处理。这样的传输方式有一个缺点:那就是包的往返时间越长通信性能越低。因此TCP引入了窗口的概念,确认应答不再是以每个分段进行,而是以更大的单位进行确认(一个窗口可以包含多个段0),也就是说:发送端主机,在发送了一个数据段之后不必要一直等待确认应答,而是继续发送。因此转发时间将会被大幅度缩短。
衍生问题2:讲讲TCP的重发控制(在使用窗口控制中,出现报文段丢失该怎么办)?
重发机制分为两种:一种是重发超时,另一种是高速重发控制。
重发超时:
重发超时是指在重发数据之前,等待足额人应答到来的那个特定时间间隔。如果超过了这个时间仍未收到确认应答,发送端将进行数据重发。重发超时的时间间隔怎么来的?它在每次发包的时候都会计算报文段往返时间及其偏差,重发超时的时间就是比这个总和稍大一点的值。
高速重发控制:
高速重发控制是用在窗口控制中的。当窗口比较大、又出现报文段丢失的情况下,同一个序列号的确认应答将会被重复不断地返回。而发送端主机如果连续3次收到同一个确认应答,就会将其所对应的数据进行重发。这种机制比重发超时更高效,因此被称作高速重发控制。
衍生问题3:讲讲TCP中的拥塞控制?
一般来说计算机网络处在一个共享的网络环境,在网络出现拥堵时如果突然发送一个较大量的数据,有可能会导致整个网络的瘫痪。因此TCP为了防止该问题的出现,在通信一开始时就会通过一个叫慢启动的算法得出的数值,对发送数据量进行控制。为了在发送端调节所要发送数据的量,定义了一个叫做“拥塞窗口”的概念。在发送数据包时,将拥塞窗口的大小与接收端主机通知的窗口大小做比较,然后按照它们当中较小的那个值,发送比其还要小的数据量。随着包的每次往返,拥塞窗口也会以1、2、4等指数函数的增长。拥塞窗口越大证明网络的吞吐量越大。
衍生问题4:TCP是如何保证可靠性的?
详细看:https://blog.csdn.net/liuchenxia8/article/details/80428157
TCP协议保证数据传输可靠性的方式主要有:1.校验和 2.确认应答与序列号 3.超时重传 4.连接管理 5.流量控制 6.拥塞控制。
1.校验和
计算方式:在数据传输的过程中,将发送的数据段都当做一个16位的整数。将这些整数加起来。并且前面的进位不能丢弃,补在后面,最后取反,得到校验和。
发送方:在发送数据之前计算检验和,并进行校验和的填充。
接收方:收到数据后,对数据以同样的方式进行计算,求出校验和,与发送方的进行比对。
2.确认应答与序列号
序列号:TCP传输时将每个字节的数据都进行了编号,这就是序列号。
确认应答:TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答。也就是发送ACK报文。这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。
3.超时重传 上面讲过
4.连接管理 也就是三次握手四次挥手
5.流量控制
接收端在接收到数据后,对其进行处理。如果发送端的发送速度太快,导致接收端的结束缓冲区很快的填充满了。此时如果发送端仍旧发送数据,那么接下来发送的数据都会丢包,继而导致丢包的一系列连锁反应,超时重传呀什么的。而TCP根据接收端对数据的处理能力,决定发送端的发送速度,这个机制就是流量控制。
窗口大小的内容实际上是接收端接收数据缓冲区的剩余大小。这个数字越大,证明接收端接收缓冲区的剩余空间越大,网络的吞吐量越大。接收端会在确认应答发送ACK报文时,将自己的即时窗口大小填入,并跟随ACK报文一起发送过去。而发送方根据ACK报文里的窗口大小的值的改变进而改变自己的发送速度。如果接收到窗口大小的值为0,那么发送方将停止发送数据。并定期的向接收端发送窗口探测数据段,让接收端把窗口大小告诉发送端。
总结来说:流量控制就是控制滑动窗口的大小的。
6.拥塞控制 上面说过
HTTP的负责定义数据,在两台计算机相互传递信息时,HTTP规定了每段数据以什么形式表达才是能够被另外一台计算机理解。而TCP所要规定的是数据应该怎么传输才能稳定且高效的传递。
TCP协议位于传输层,而HTTP协议位于应用层。HTTP可以利用TCP在两台电脑(通常是Web服务器和客户端)之间传输信息。
衍生问题1:既然TCP是有状态的,为什么HTTP建立在TCP之上是无状态的?
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来。但是发送完不会记录任何信息。
HTTP 是一个无状态协议,这意味着每个请求都是独立的,Keep-Alive 没能改变这个结果。
HTTP 协议这种特性有优点也有缺点,优点在于解放了服务器,每一次请求都不会造成不必要的连接占用,缺点在于每次请求会传输大量重复的内容信息。
客户端与服务器进行动态交互的 Web 应用程序出现之后,HTTP 无状态的特性严重阻碍了这些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。于是,两种用于保持 HTTP 连接状态的技术就应运而生了,一个是 Cookie,而另一个则是 Session。
答案:第四点
(1)IP是无状态的,它只负责将一个IP包发送到指定的IP地址上去。它不会考虑这个包与前面已经发送的包和后面的包的联系。(可能是重发包、可能是不连续包,它不管)。
(2)TCP是有状态的,它通过包头中的一些控制字段(序列编码等)来表明各个包之间的关系(前后关系,重包与否等等)。所以,通过这个协议你可以做到一个可靠的传输。那么TCP是面向连接的协议是什么意思呢?其实这里的面向连接其实就是“三次握手”。三次握手,首先可以保证对方的存在,其次握手的所交换的内容是为将来进行有状态的传输做准备。
(3) UDP是无状态的,它仅仅是在IP上加了Port,其他的事情什么也不干。这样它不可能做到可靠的传输,同样也不需要连 接。
(4) HTTP是无状态的。HTTP的一次完整协议动作,里面是使用有状态的TCP协议来完成的。但是每次协议动作之间没有任何关系。例如:第7次请求HTTP协议包,但是它本身并不知道这个包是为了什么?它或许是因为上次没有请求成功而重传,或许是上次的后续请求,或许是其他的,这些HTTP自身都不知道。
http(Hypertext transfer protocol)超文本传输协议,通过浏览器和服务器进行数据交互,进行超文本(文本、图片、视频等)传输的规定。
区别:
1.HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
2.使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,需要交费。
3.HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
4.http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
5.HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以HTTPS 比 HTTP 要更耗费服务器资源。
https采用共享密钥加密和公开密钥加密两者并用的混合加密机制密码。
衍生问题1:ca证书的理解?
衍生问题2:什么是共享密钥加密?什么是公开密钥加密?(什么是对称密钥加密?什么是非对称密钥加密?)
共享密钥加密(对称密钥加密)是指采用相同的密钥对报文进行加密解密。这样的问题在于如果密钥被截取了就相当于没有加密了。
公开密钥加密(非对称密钥加密)是指加密和解密所使用的密钥是不同的。其中加密所用的密钥是对外界公开的,称为公钥。而解密所用的密钥是只有自己知道的,称为私钥。用公钥加密过的信息只能用私钥才能解密。
衍生问题3:HTTPS请求过程?(一次HTTPS请求要进行两次HTTP传输)
1.客户端发出https请求,请求服务端建立SSL连接;
2.服务端收到https请求,申请或自制数字证书,得到公钥和服务端私钥,并将公钥发送给客户端;
3.客户端验证公钥,不通过验证则发出警告,通过验证则产生一个随机的客户端私钥;
4.客户端将公钥与客户端私钥进行对称加密后传给服务端;
5.服务端收到加密内容后,通过服务端私钥进行非对称解密,得到客户端私钥;
6.服务端将客户端私钥和内容进行对称加密,并将加密内容发送给客户端;
7.客户端收到加密内容后,通过客户端私钥进行对称解密,得到内容。
衍生问题4:https的原理?
过程:浏览器将自己支持的一套加密规则发给服务器,服务器从中选择一组加密算法和Hash算法,服务器向浏览器发送(证书,网站地址,加密公钥,颁发机构),浏览器对其进行验证,通过后显示安全连接,浏览器生成一串随机数,并使用服务证书中的公钥对其加密,加密后的随机数发给服务器,服务器用私钥对其解密,该随机数就是双方通信的密钥
注意:
1. 非对称加密算法用于握手过程中加密生成的密码(公钥加密,私钥解密),对称加密算法对真正传输的数据进行加密,HASH算法是验证数据的完整性
2. 由于浏览器生成的密码是整个数据加密的关键,因此在传输的时候使用了非对称加密算法对其加密
HTTP/2传输数据量的大幅减少,主要有两个原因:以二进制方式传输和Header压缩。我们先来介绍二进制传输,
1.二进制分帧传输。HTTP/2 采用二进制格式传输数据,而非HTTP/1.x 里纯文本形式的报文 ,二进制协议解析起来更高效。HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。HTTP/2 中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。
2.Header压缩。HTTP/2并没有使用传统的压缩算法,而是开发了专门的"HPACK”算法,在客户端和服务器两端建立“字典”,用索引号表示重复的字符串,还采用哈夫曼编码来压缩整数和字符串,可以达到50%~90%的高压缩率。
具体来说:
在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;
首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新;
每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值;
例如下图中的两个请求, 请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销。
3.多路复用。在 HTTP/2 中引入了多路复用的技术。多路复用很好的解决了浏览器限制同一个域名下的请求数量的问题,同时也接更容易实现全速传输,毕竟新开一个 TCP 连接都需要慢慢提升传输速度。
在 HTTP/2 中,有了二进制分帧之后,HTTP /2 不再依赖 TCP 链接去实现多流并行了,在 HTTP/2中,
同域名下所有通信都在单个连接上完成。
单个连接可以承载任意数量的双向数据流。
数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装。
这一特性,使性能有了极大提升:
同个域名只需要占用一个 TCP 连接,使用一个连接并行发送多个请求和响应,这样整个页面资源的下载过程只需要一次慢启动,同时也避免了多个TCP连接竞争带宽所带来的问题。
并行交错地发送多个请求/响应,请求/响应之间互不影响。
在HTTP/2中,每个请求都可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。
如上图所示,多路复用的技术可以只通过一个 TCP 连接就可以传输所有的请求数据。
4.Server Push。HTTP2还在一定程度上改变了传统的“请求-应答”工作模式,服务器不再是完全被动地响应请求,也可以新建“流”主动向客户端发送消息。比如,在浏览器刚请求HTML的时候就提前把可能会用到的JS、CSS文件发给客户端,减少等待的延迟,这被称为"服务器推送"( Server Push,也叫 Cache push)
衍生问题1:分别讲讲这些新特性?
1..二进制分帧传输。HTTP/2 采用二进制格式传输数据,二进制协议解析起来更高效。HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。
2.Header压缩。HTTP/2并没有使用传统的压缩算法,而是开发了专门的"HPACK”算法,在客户端和服务器两端建立“字典”,用索引号表示重复的字符串,还采用哈夫曼编码来压缩整数和字符串,可以达到50%~90%的高压缩率。
3.多路复用。在 HTTP/2 中引入了多路复用的技术。多路复用解决了浏览器限制同一个域名下的请求数量的问题,同一个域名下的所有通信都可以在单个连接上完成。
4.服务器推送。HTTP2还在一定程度上改变了传统的“请求-应答”工作模式,服务器不再是完全被动地响应请求,也可以新建“流”主动向客户端发送消息。比如,在浏览器刚请求HTML的时候就提前把可能会用到的JS、CSS文件发给客户端,减少等待的延迟,这被称为"服务器推送"( Server Push,也叫 Cache push)。
HTTP缓存主要用在对一些实时性要求不高的静态文件进行的缓存,往往都是存在浏览器端,防止这些“多余”的请求重复的访问服务器,对服务器造成压力,从而提高网站的性能。http协议提供了两种维度来让缓存失效:时间和文件的修改。
1.利用时间来让缓存失效
时间维度很简单,就是设定一个缓存时间段,过了这个时间段,缓存就自动失效了,浏览器就会发起请求获取文件。这个设定时间的http字段就是cache-control
字段。
cache-control
可设置的字段值有:
2.通过查看文件的修改来让缓存失效
浏览器先请求服务获得文件后,服务器会返回该文件的最后修改时间Last-Modified
,作为文件的一个标识,下次浏览器请求的时候,会带着这个标识去请求(此时为If-Modified-Since
),然后服务器做校验,如果说时间标识If-Modified-Since
等于服务器的文件修改时间,则说明没有修改,返回304状态码,浏览器从缓存中获取文件,但是如果浏览器保存的时间标识If-Modified-Since
小于服务器端的文件修改时间,那么,说明文件发生了修改,浏览器就会重新获取新的文件。
(If-Modified-Since
的时间如果大于服务器端文件的时间,会被认为是错误的请求)
虽然通过文件最后修改时间作为标识已经很完美了,但是,还是可能存在一个问题:就是有可能服务器端的文件修改后,又改回原来的样子,这样,虽然文件最后修改时间变了,但是,文件内容并没有改变。这样还是会有多余的请求到达服务器,该如何处理呢?
可以将文件内容作为一个唯一标识,例如可以对文件内容取MD5值(或者哈希值)作为字段(etag
)也传给浏览器端,假如这个文件内容没变化,那么MD5值也不会改变。那么,处理流程就变成了这样:服务器端先判断文件修改时间是否发生了变化,如果发生了变化,那么再对比浏览器传来的If-None-Match
即浏览器端保留的E-tag
值,如果发生了变化,则证明文件修改了,需要浏览器重新下载文件,如果没有,则证明 文件内容没变化,返回304状态码。
衍生问题1:说说强缓存?协商缓存?
浏览器强缓存是指当请求一个资源时,直接从本地的浏览器缓存中读取,不发起HTTP请求。通过设置请求头Cache-Control:max-age=xxxxx来设置强缓存。
当浏览器强缓存过期后,就会触发协商缓存机制。这个时候需向服务器发送一个http请求,带上如下列表中的头部信息,如果符合规则(即服务器跟客户端资源一致),直接返回304,不再返回资源内容;否则,返回状态码200与资源内容;最后,更新缓存头信息。
衍生问题2:Expires与Cache-Control有什么区别?
1.Expires 是以前用来控制缓存的http头,Cache-Control是新版的API。
2.Cache-Control设置时间长度过期,Expires 设置时间点过期。
Expires: Wed, 21 Oct 2015 07:28:00 GMT
3.如果在Cache-Control响应头设置了 "max-age" 指令,那么 Expires 头会被忽略。
衍生问题1:讲讲DNS查询的过程?
1. 浏览器先检查自身缓存中有没有被解析过的这个域名对应的ip地址,如果有,解析结束。同时域名被缓存的时间也可通过TTL属性来设置。
2. 如果浏览器缓存中没有(专业点叫还没命中),浏览器会检查操作系统缓存中有没有对应的已解析过的结果。而操作系统也有一个域名解析的过程。在windows中可通过c盘里一个叫hosts的文件来设置,如果你在这里指定了一个域名对应的ip地址,那浏览器会首先使用这个ip地址。
3. 如果至此还没有命中域名,才会真正的请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。
4. 如果LDNS仍然没有命中,就直接跳到Root Server 域名服务器请求解析
5. 根域名服务器返回给LDNS一个所查询域的主域名服务器(gTLD Server,国际顶尖域名服务器,如.com .cn .org等)地址
6. 此时LDNS再发送请求给上一步返回的gTLD
7. 接受请求的gTLD查找并返回这个域名对应的Name Server的地址,这个Name Server就是网站注册的域名服务器
8. Name Server根据映射关系表找到目标ip,返回给LDNS
9. LDNS缓存这个域名和对应的ip
10. LDNS把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,域名解析过程至此结束.
衍衍生问题1:DNS解析是基于UDP还是TCP?为什么?
DNS在进行区域传输的时候使用TCP,普通的查询使用UDP。
DNS区域传输的时候使用TCP协议:
1.辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传送,进行数据同步。区域传送使用TCP而不是UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多。
2.TCP是一种可靠连接,保证了数据的准确性。
域名解析时使用UDP协议:
客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。
如果在域名解析时采用TCP协议,那么域名解析时间=TCP连接时间 + DNS交易时间。而采用UDP协议的话域名解析时间就只等于DNS交易时间。很显然,采用UDP传输,DNS域名解析时间更小。
很多人可能会说不就多一次TCP连接时间吗?
其实不是的。在很多时候,用户在访问一些冷门网站时,由于DNS服务器没有冷门网站的解析缓存,需要到域名根服务器、一级域名服务器、二级域名服务器迭代查询,直到查询到冷门网站的权威服务器,这中间可能涉及到多次的查询。如果使用TCP传输,多几次查询,就多几次TCP连接时间,这多出来的时间不容小觑。
HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),在使用长连接的情况下,当一个网页打开完成后,通过在响应头加入Connection:keep-alive,客户端和服务器之间用于传输HTTP数据的TCP连接就不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间。通过设置Keep-Alive: timeout=20,表示这个TCP通道可以保持20秒。另外还可能有max=XXX,表示这个长连接最多接收XXX次请求就断开。
衍生问题1:TCP的keep alive和HTTP的Keep-alive有什么区别?
TCP的keep alive是检查当前TCP连接是否活着;HTTP的Keep-alive是要让一个TCP连接活久点。它们是不同层次的概念。TCP keep alive的表现:当一个连接“一段时间”没有数据通讯时,一方会发出一个心跳包(Keep Alive包),如果对方有回包则表明当前连接有效,继续监控。这个“一段时间”可以设置。
1.HTTP/0.9 仅支持GET请求,不支持请求头
2.HTTP/1.0 默认短连接(一次请求建立一次TCP连接,请求完就断开),支持GET、POST、 HEAD请求
3.HTTP/1.1 默认长连接(一次TCP连接可以多次请求);支持PUT、DELETE、PATCH等六种请求
4.HTTP/2.0 新增二进制分帧传输、header压缩、多路复用、服务器推送。
衍生问题1:301、302、307状态码有何区别?
301是永久重定向,而302、307是临时重定向。
302和307的区别在于使用302重定向时会改变请求的方法(例如post变成了get),而使用307则不会。
301状态码:资源位置永久改变, 需要重定向, 通常用于将HTTP请求迁移到HTTPS。
衍生问题2:http跳转到https时为什么会存在POST改为GET请求的情况?
因为在使用301、302状态码进行重定向的时候,浏览器会判断这个请求的类型,如果这不是一个GET或者HEAD请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。