OSI网络模型与TCP/IP网络模型

OSI将计算机通信网络划分为七个不同的层级,从下到上分别是物理层,链路层,网络层,传输层,会话层,表示层,应用层;

每个层级负责特定的功能,建立在下方层级之上,并为上方层级提供服务.

TCP/IP网络模型则为四层,从上到下分别是应用层,网络层,传输层,链路层;

应用层相当于osi模型的上三层,主要负责提供与应用程序交互的接口,比如http,smtp,ftp等;

传输层主要负责端到端的数据传输,主要协议有tcp,udp;tcp是面向连接的、可靠的协议,确保数据的完整性和正确性;而udp是面向无连接的,可靠性不高,主要用于实时性场景,比如实时音视频流.

网络层主要协议是ip,负责数据包的路由与转发,找到一条最佳路径,将数据包从源主机转发到目标主机.使用ip地址表示网络和主机,并负责逻辑地址寻址

链路层相当于链路层和物理层,主要是物理传输媒介的传输,比如wifi,以太网,还提供差错检测和纠错的功能.也包含硬件地址的管理.

从输入 URL 到页面展示到底发生了什么?

输入网址,解析url,在网址合法且有效的前提下,准备发送请求

先去浏览器缓存里面找,有没有缓存请求的资源,如果有直接返回,如果没有进入下一步网络请求,http缓存。

网络请求前,要先进行DNS域名解析:按照本地浏览器缓存-本地host文件-路由器缓存-DNS服务器缓存-根DNS服务器缓存的顺序去找域名对应的IP,直到找到为止,这边还涉及到DNS的查询过程

找到对应IP地址后,浏览器与服务器IP三次握手建立TCP连接

连接建立后浏览器构建请求行,请求头等请求信息,并把和该域名相关的cookie附加到请求头中,如果是HTTPS的话,还涉及加解密流程;

服务器解析请求信息,处理请求并响应

浏览器解析响应并渲染页面

TCP四次挥手断开连接

-解析响应头,若响应状态码为301302,会重定向到新地址;若响应的数据类型是字节流类型,会将请求提交给下载管理器,如果是HTML,浏览器解析HTML文件,创建DOM树,解析CSS,将CSS和DOM树合并构建渲染树,最后布局和绘制渲染树,完成页面展示

DNS的查询过程

DNS 用来将主机名和域名转换为IP地址, 其查询过程一般通过以下步骤:

  1. 本地DNS缓存检查:首先查询本地DNS缓存,如果缓存中有对应的IP地址,则直接返回结果。
  2. 如果本地缓存中没有,则会向本地的DNS服务器(通常由你的互联网服务提供商(ISP)提供, 比如中国移动)发送一个DNS查询请求。
  3. 如果本地DNS解析器有该域名的ip地址,就会直接返回,如果没有缓存该域名的解析记录,它会向根DNS服务器发出查询请求。根DNS服务器并不负责解析域名,但它能告诉本地DNS解析器应该向哪个顶级域(.com/.net/.org)的DNS服务器继续查询。
  4. 本地DNS解析器接着向指定的顶级域名DNS服务器发出查询请求。顶级域DNS服务器也不负责具体的域名解析,但它能告诉本地DNS解析器应该前往哪个权威DNS服务器查询下一步的信息。
  5. 本地DNS解析器最后向权威DNS服务器发送查询请求。 权威DNS服务器是负责存储特定域名和IP地址映射的服务器。当权威DNS服务器收到查询请求时,它会查找"example.com"域名对应的IP地址,并将结果返回给本地DNS解析器。
  6. 本地DNS解析器将收到的IP地址返回给浏览器,并且还会将域名解析结果缓存在本地,以便下次访问时更快地响应。
  7. 浏览器发起连接: 本地DNS解析器已经将IP地址返回给您的计算机,您的浏览器可以使用该IP地址与目标服务器建立连接,开始获取网页内容。

HTTP请报文和响应报文的构成以及常用字段

请求行,请求头,空行,请求体

(方法,资源路径,http版本)

请求头字段:HOST,ACCEPT,CACCEPT-ENCODING,connection,cookie,contenttype,contentlength,if modified since;if none match,authrization

状态行响应头空行响应体

(版本,状态码,状态信息)

响应头字段:expires,etag,location,set-cookie,contenttype,contentlength,access-control-allow-origin:指定哪些域可以访问

GET和POST的区别

用途:GET获取资源;POST提交数据,可能影响服务器

参数传递:get参数写在url中,传输的数据量较小;而post参数在请求体中,请求信息没有长度限制

幂等性:get是幂等的,post可能会修改服务器上的资源,所以不幂等

缓存机制上:get会被浏览器主动缓存,post不会,除非手动设置

时间消耗:get发送一个请求,浏览器将header和data一起发送出去,服务器响应200;post先发送header,服务器响应100,浏览器在发送data,服务器响应200ok

强缓存和协商缓存

强缓存和协商缓存是HTTP缓存机制的两种类型,它们用于减少服务器的负担和提高网页加载速度。

强缓存:客户端在没有向服务器发送请求的情况下,直接从本地缓存中获取资源。

Expires强缓存:设置一个强缓存时间,此时间范围内,从内存中读取缓存并返回。但是因为Expires判断强缓存过期的机制是获取本地时间戳,与之前拿到的资源文件中的Expires字段的时间做比较来判断是否需要对服务器发起请求。这里有一个巨大的漏洞:“如果我本地时间不准咋办?”所以目前已经被废弃了。

Cache-Control强缓存:目前使用的强缓存是通过HTTP响应头中的Cache-Control字段实现,通过max-age来告诉浏览器在指定时间内可以直接使用缓存数据,无需再次请求。

协商缓存:当强缓存失效时,浏览器会发送请求到服务器,通过ETag或Last-Modified等HTTP响应头与服务器进行验证,以确定资源是否被修改。如果资源未修改,服务器返回304 Not Modified状态码,告知浏览器使用本地缓存;如果资源已修改,则返回新的资源,浏览器更新本地缓存。这种方式需要与服务器通信,但可以确保用户总是获取最新的内容。

基于Last-Modified的协商缓存

Last-Modified 是资源的最后修改时间,服务器在响应头部中返回。

当客户端读取到Last-modified的时候,会在下次的请求标头中携带一个字段:If-Modified-Since,而这个请求头中的If-Modified-Since就是服务器第一次修改时候给他的时间

服务器比较请求中的 If-Modified-Since 值与当前资源的 Last-Modified 值,如果比对的结果是没有变化,表示资源未发生变化,返回状态码 304 Not Modified。如果比对的结果说资源已经更新了,就会给浏览器正常返回资源,返回200状态。

但是这样的协商缓存有两个缺点

因为是更改文件修改时间来判断的,所以在文件内容本身不修改的情况下,依然有可能更新文件修改时间(比如修改文件名再改回来),这样,就有可能文件内容明明没有修改,但是缓存依然失效了。

当文件在极短时间内完成修改的时候(比如几百毫秒)。因为文件修改时间记录的最小单位是秒,所以,如果文件在几百毫秒内完成修改的话,文件修改时间不会改变,这样,即使文件内容修改了,依然不会返回新的文件。

基于ETag的协商缓存

将原先协商缓存的比较时间戳的形式修改成了比较文件指纹(根据文件内容计算出的唯一哈希值)。

ETag 是服务器为资源生成的唯一标识符(文件指纹),可以是根据文件内容计算出的哈希值,服务端将其和资源一起放回给客户端。

客户端在请求头部的 If-None-Match 字段中携带上次响应的 ETag 值。

服务器比较请求中的 If-None-Match 值与当前资源的 ETag 值,如果匹配,表示资源未发生变化,返回状态码 304 Not Modified。如果两个文件指纹不吻合,则说明文件被更改,那么将新的文件指纹重新存储到响应头的ETag中并返回给客户端

HTTP1.0 1.1 2.0 3.0了解

1.0与1.1

持久连接:HTTP/1.1 默认支持持久连接,允许在一个TCP连接上发送多个HTTP请求和响应,减少了连接建立和关闭的开销。而HTTP/1.0 默认为短连接,每次请求都需要建立一个TCP连接,并通过Connection: keep-alive头来实现持久连接。

道化:HTTP/1.1 支持管道化(不是默认开启),允许客户端在第一个请求的响应到达之前发送多个请求,这可以减少等待时间,提高效率。HTTP/1.0不支持管道化。

注意:但是服务器仍需要按照请求到达的顺序去处理响应,如果某个请求耗时较长,那么后面的请求处理都会被阻塞,即响应的队头阻塞现象。1.1解决了请求的队头阻塞现象,但没有解决响应的队头阻塞现象。

host头:HTTP/1.1 引入了Host头,允许客户端指定请求的主机名,这使得在同一台服务器上托管多个域名成为可能。

range头域实现带宽优化:HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能, 而HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content)

错误处理状态码:HTTP/1.1 增加了一些新的HTTP状态码,如100 Continue,用于增强错误处理和请求的中间响应。

缓存控制头:HTTP1.0主要使用If-Modified-Since/Expires来做为缓存判断的标准,而HTTP1.1则引入了更多的缓存控制策略例如Etag / If-None-Match等更多可供选择的缓存头来控制缓存策略。

1.1与2.0:

协议格式:HTTP/2.0 采用二进制格式传输数据,而非HTTP/1.1 的文本格式,将数据划分为二进制帧传输,分为头信息帧和数据帧,使得解析更高效,减少了解析时间。

多路复用:HTTP/2.0 支持多路复用,允许在单个TCP连接上并行交错发送多个请求和响应,解决了HTTP/1.1 中的响应队头阻塞问题。多个Stream复用在同一条tcp连接上,不同的http请求有着不同的流标识符,不同流间可以乱序发送,在接收端根据流标识符有序组装HTTP信息,做到并发不同流,即并行交错的发送请求与响应

注意:但仍然存在队头阻塞的问题,不过问题是在传输层:基于tcp协议,而tcp又是面向字节流的,保证数据的完整性和有序性,若前一个字节没有到达,那么后面的字节数据都将在内核缓冲区等待,直至该字节到达,才会被内核返回给http层应用。

tcp连接》一个或多个Stream》一个或多个message》一条或多条Frame;

http消息可以有多个Frame构成,一个Frame可以由多个tcp报文构成。

头部压缩:HTTP/2.0 引入了HPACK 压缩算法,对请求和响应的头部信息进行压缩,减少了冗余头部信息的传输,提高了传输效率。

服务器推送:HTTP/2.0 允许服务器主动推送资源给客户端,而不需要客户端明确请求,这可以减少页面加载时间。服务器在推送资源时,通过PUSH_PROMISE帧传输http头部,并通过帧中的Promise Stream id字段告诉客户端,接下来在哪个偶数号Stream中发送包体。

请求优先级和依赖:HTTP/2.0 允许客户端为请求设置优先级,通过帧头中的标志位实现。并表达请求之间的依赖关系,资源加载更加有序。

3.0:

HTTP/3基于QUIC协议,QUIC 又使用UDP协议,所以没有队头阻塞问题

  1. 零 RTT 连接建立:首次连接肯定是需要1 RTT的,0 RTT的优势是在连接的后续建立的 ,从而减少了连接延迟,加快了页面加载速度。2.0需要三次握手四次tls握手共计3RTT时延才能发出请求。

  2. 连接迁移:QUIC 允许在网络切换(如从 Wi-Fi 到移动网络)时,将连接迁移到新的 IP 地址,从而减少连接的中断时间。

  3. 基于TCP的连接是通过四元组来确定一条连接,当发生网络切换,ip地址变化了,就需要断开连接,然后重连,三次tcp握手,四次tls握手,tcp慢启动阶段,让用户感觉网络突然卡顿了一下。

  4. 基于UDP的QUIC协议仅仅通过连接ID去识别对端身份,即便网络切换,只要仍保有上下文信息(如连接id,tls密钥),就可以无缝复用原连接。

  5. 向前纠错机制:每个数据包除了它本身的内容之外,还包括了部分其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。向前纠错牺牲了每个数据包可以发送数据的上限,但是减少了因为丢包导致的数据重传。

  6. 安全性:HTTP/3默认使用TLS加密,确保了数据传输的安全性。

  7. 使用QPack算法压缩头部信息。

3.0如何实现的0RTT连接建立

QUIC协议并非与TLS分层,而是内部包含TLS,它在自己的帧里就可以携带TLS的记录,仅需一次握手就可以同时完成连接的建立和密钥的协商。握手是为了确认双方的连接ID。在第二次链接的时候,甚至应用数据包还可以和quic握手信息(连接信息+ tls信息)一起发送,达到0rtt的效果

细品HPack和QPack算法

客户端和服务端都会建立和维护”字典“,用长度较小的索引表示重复的字符串,再用huffman编码压缩数据。

HPack算法包括三个组成部分:

  1. 静态表编码:http2.0为高频出现在头部的字符串和字段建立了一张静态表,共61组,写在http2框架里面,不会变化
  2. 动态表编码:使用前提必须在同一个连接上,重复传输完全相同的HTTP头部。若动态表无限增大超过上限,服务器将会断开HTTP2的连接以释放内存。具有时序性:若首次出现的请求出现了丢包,后续收到的请求就因未建立好动态表而难以解析出头部,阻塞到丢失的数据包重传过来。
  3. Huffman编码

QPack:

  1. 静态表编码:91组;

  2. 动态表编码:利用两个特殊的单向流传递动态表信息与响应。

  3. 一个单向流用来传递字典:当客户端面对不属于静态表的头部,可以通过该流发送字典到对端。

  4. 一个单向流用来传达响应:若收到字典并更新至本地动态表,那么响应对方,以后就可以用这个字典来编码了。

HTTP和HTTPS的区别

HTTP明文传输,数据传输存在风险;80端口

HTTPS增设一层ssl/tls加密层,传输加密报文;

HTTPS连接建立除了TCP三次握手,还需要ssl四次握手,443端口;还需要项CA机构申请数字证书,保证服务器是可信的

HTTPS加密原理

对称加密 双方使用同一把密钥进行加密和解密,算法速度非常快,但密钥的安全性十分重要,一旦密钥泄露,数据就可能被篡改

非对称加密 由一对配套密钥进行加解密;公钥加密的报文只有私钥能够解密,私钥加密的只有对应的公钥才能解开.

HTTPS采用的是对称与非对称混合的加密算法.在通信建立前,采用非对称加密算法传输会话密钥,通信过程中全部采用通信密钥这种对称加密的方式进行加密解密.

如何保证内容不被篡改

摘要算法+数字签名 传输内容附带内容的指纹,接收后也将接收到的内容计算得到指纹,将两个指纹对比,若一致则说明没有发生变化

摘要算法用来计算内容的哈希值,生成唯一标识符

数字签名即消息的哈希值经过私钥加密的结果

如何保证发送方身份可信

非对称加密+数字证书

采用非对称加密,服务器利用私钥加密获得数字签名,将数字签名与原始消息一并发送给接收端

接收端收到后用发送方的公钥去解密验证签名,得到摘要值(指纹),再对原始消息摘要进行摘要算法得到指纹,比对相同则内容无篡改,数字签名有效,信息来源可靠

数字证书用来验证身份,解决中间人将双方公钥换成自己公钥的问题,就是保证这一对密钥确实是配套的.

  1. 服务器将服务器公钥注册到CA
  2. CA用CA私钥加密(服务器的公钥+CA的数字签名),得到数字证书
  3. 客户端拿到证书后,用CA公钥解密确认证书真实性.注:CA公钥已经事先置入浏览器或操作系统,所以一定是配套的
  4. 再利用证书里的服务器公钥加密会话密钥,传输给服务器.

HTTPS建立流程

  1. 客户端向服务器发送加密通信请求
  2. 服务端产生一对公私钥,将自己的公钥发送给CA机构,CA机构也有一对钥匙,用自己的私钥加密得到数字证书
  3. 服务端响应请求,将CA数字证书发送给客户端
  4. 客户端用内置的CA公钥解析数字证书,确认真实性后从证书中取出服务器公钥
  5. 生成随机码key用作会话密钥
  6. 利用公钥加密会话密钥发送给服务端
  7. 服务端接收后用私钥进行解密,得到会话密钥
  8. 双方使用该会话密钥进行数据传输

TCP UDP的区别

  1. TCP是面向连接的协议,需要在数据传输前建立连接;UDP是无连接的,不需要建立连接。
  2. TCP提供可靠的数据传输,保证数据包的顺序和完整性;UDP不保证数据包的顺序或完整性。
  3. TCP具有拥塞控制机制,可以根据网络状况调整数据传输速率;UDP没有拥塞控制,发送速率通常固定。
  4. TCP通过滑动窗口机制进行流量控制,避免接收方处理不过来;UDP没有流量控制。
  5. TCP能够检测并重传丢失或损坏的数据包;UDP不提供错误恢复机制。
  6. TCP有复杂的报文头部,包含序列号、确认号、窗口大小等信息;UDP的报文头部相对简单(源端口,目标端口,包长度,校验和)。
  7. 由于TCP的连接建立、数据校验和重传机制,其性能开销通常比UDP大;UDP由于简单,性能开销小。
  8. TCP基于流的传输不认为消息是一条一条的,没有保护消息边界,可能会出现粘包现象;UDP面向消息传输,室友消息保护边界的,接收方一次只接受一条消息,不存在粘包问题. 如三个数据包2k4k6k,UDP不管接收方缓存有多大,至少要三次以上的发送才能发完,TCP如果接收方缓冲区特别大的话一次就可以发完.
  9. 适用场景:TCP适用于需要可靠传输的应用,如网页浏览、文件传输等;UDP适用于对实时性要求高的应用,如语音通话、视频会议等。

TCP如何实现可靠性

序列号,校验和,确认应答,超时重传,拥塞控制,流量控制

  1. 序列号:每个TCP报文都有序列号,用来保证数据包的顺序正确
  2. 校验和:tcp使用校验和来判断传输过程中是否发生错误,如果检测到错误,那么会立刻丢掉这个包,并等待重传
  3. 确认应答:接收方接收数据后需要向发送方发送确认号,如果发送方在一定时间内没有接收到确认好,那么会重新发送数据
  4. 超时重传:发送方设置一个定时器,如果在定时器超时之前没有收到确认,那么会进行重传
  5. 拥塞控制:TCP能根据实时网络状况动态调整发送速率,避免网络拥塞,比如在一开始会以一个比较小的发送窗口发送数据,当不断接受到接收方发来的确认报文之后,会逐步增大发送窗口的大小,以一个指数级….
  6. 流量控制:TCP使用滑动窗口机制,避免接收方接受不过来

三次握手与四次挥手

(1) 三次握手的过程

  1. 第一次握手:客户端向服务器发送一个SYN (同步序列编号)报文,请求建立连接,客户端进入SYN_SENT 状态。
  2. 第二次握手:服务器收到SYN 报文后,如果同意建立连接,则会发送一个SYN-ACK (同步确认)报文作为响应,同时进入SYN_RCVD 状态。
  3. 第三次握手:客户端收到服务器的SYN-ACK 报文后,会发送一个ACK (确认)报文作为最终响应,之后客户端和服务器都进入ESTABLISHED 状态,连接建立成功。

(2)为什么需要三次握手

通过三次握手,客户端和服务器都能够确认对方的接收和发送能力。第一次握手确认了客户端到服务器的通道是开放的;第二次握手确认了服务器到客户端的通道是开放的;第三次握手则确认了客户端接收到服务器的确认,从而确保了双方的通道都是可用的。

而如果仅使用两次握手,服务器可能无法确定客户端的接收能力是否正常,比如客户端可能已经关闭了连接,但之前发送的连接请求报文在网络上延迟到达了服务器,服务器就会主动去建立一个连接,但是客户端接收不到,历史连接建立导致资源的浪费。而四次握手可以优化为三次。

SYN攻击:攻击者发送大量伪造的SYN请求到目标服务器,但不完成后续的握手过程,让服务器一直等待确认,消耗服务器资源(如半连接队列和系统资源),半连接队列满了后,后续收到的SYN报文就会被丢弃,导致无法与客户端建立连接

(1)四次挥手的过程

  1. 第一次挥手:客户端发送一个FIN报文给服务端,表示自己要断开数据传送,报文中会指定一个序列号 (seq=x)。然后,客户端进入FIN-WAIT-1 状态。
  2. 第二次挥手:服务端收到FIN报文后,回复ACK报文给客户端,且把客户端的序列号值+1,作为ACK报文的序列号(seq=x+1)。然后,服务端进入CLOSE-WAIT(seq=x+1)状态,客户端进入FIN-WAIT-2状态。
  3. 第三次挥手:等待服务端处理完数据,也要断开连接时,发送FIN报文给客户端,且指定一个序列号(seq=y+1),随后服务端进入LAST-ACK状态。
  4. 第四次挥手:客户端收到FIN报文后,发出ACK报文进行应答,并把服务端的序列号值+1作为ACK报文序列号(seq=y+2)。此时客户端进入TIME-WAIT状态。服务端在收到客户端的ACK 报文后进入CLOSE 状态。如果客户端等待2MSL没有收到回复,才关闭连接。

(2)为什么需要四次挥手

TCP是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。 当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后才会完全关闭 TCP 连接。因此两次挥手可以释放一端到另一端的TCP连接,完全释放连接一共需要四次挥手。

只有通过四次挥手,才可以确保双方都能接收到对方的最后一个数据段的确认,主动关闭方在发送完最后一个ACK后进入TIME-WAIT 状态,这是为了确保被动关闭方接收到最终的ACK ,如果被动关闭方没有接收到,它可以重发FIN 报文,主动关闭方可以再次发送ACK

而如果使用三次挥手,被动关闭方可能在发送最后一个数据段后立即关闭连接,而主动关闭方可能还没有接收到这个数据段的确认。

为什么需要TIME_WAIT状态

主动关闭的一方,才会有TIME_WAIT状态

  1. 防止历史连接中的数据,被后面相同四元组连接错误的吸收

若没有这个状态,直接进入CLOSE,一些因为网络状况滞留的数据包可能会被传递给新连接,经过2MSL,足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络中都消失,再出现的数据包一定是新连接所产生的

  1. 保证最后的ack能够让被动关闭方接收,帮助被动关闭方关闭

如果最后一次ack报文丢失,客户端又直接进入了CLOSE,接收端一直在等待ACK,没有收到就会重发FIN,可客户端已经关闭

为什么TIME_WAIT等待2MSL

MSL是报文最大生存时间

2MSl是从关闭方收到FIN报文发送ACK报文开始计时的,一个MSL保证ack能够到达对端,一个MSL保证接收方没有收到ACK,重传的FIN能够到达关闭方.

关闭方一旦重新收到FIN,将会重新开始计时

拥塞控制机制

TCP拥塞控制可以在网络出现拥塞时动态地调整数据传输的速率,以防止网络过载

  1. 慢启动(Slow Start): 初始阶段,TCP发送方会以较小的发送窗口开始传输数据。随着每次成功收到确认的数据,发送方逐渐增加发送窗口的大小,实现指数级的增长,这称为慢启动。这有助于在网络刚开始传输时谨慎地逐步增加速率,以避免引发拥塞。

  2. 拥塞避免(Congestion Avoidance): 一旦达到一定的阈值(通常是慢启动阈值),TCP发送方就会进入拥塞避免阶段。在拥塞避免阶段,发送方以线性增加的方式增加发送窗口的大小,而不再是指数级的增长。这有助于控制发送速率,以避免引起网络拥塞。

  3. 若发生超时重传,往往意味着网络状况非常糟糕,将会把慢启动阈值调整为当前窗口的一半,拥塞窗口大小设置为1,回到慢启动阶段。

  4. 快速重传(Fast Retransmit): 如果发送方连续收到相同的确认,它会认为发生了数据包的丢失,但能收到确认,网络状况也没有那么糟糕,会快速重传未确认的数据包,而不必等待超时。这有助于更快地恢复由于拥塞引起的数据包丢失。

  5. 快速恢复(Fast Recovery): 在发生快速重传后,TCP进入快速恢复阶段。在这个阶段,发送方不会回到慢启动阶段,而是将慢启动阈值设置为当前窗口的一半,并将拥塞窗口大小设置为慢启动阈值加上已确认但未被快速重传的数据块的数量。每收到一个重复的ack,窗口大小就多增加1,若收到新的ack意味着先前丢失的数据包全部重传完毕,将窗口大小设置为阈值,进入拥塞避免阶段。这有助于更快地从拥塞中恢复。

流量控制机制

流量控制就是让发送方发送速率不要过快,让接收方来得及接收。利用滑动窗口机制就可以实施流量控制,主要方法就是动态调整发送方和接收方之间数据传输速率。

  • 每个TCP报文段都包含一个窗口字段,该字段指示发送方可以发送多少字节的数据而不等待确认。这个窗口大小是动态调整的。
  • 接收方定期发送确认(ACK)报文,告知发送方已成功接收数据。并通过报文中的窗口字段告诉发送方自己当前的可接收窗口大小。这是接收方缓冲区中还有多少可用空间。
  • 流量控制的目标: 流量控制的目标是确保发送方不要发送超过接收方缓冲区容量的数据。如果接收方的缓冲区快满了,它会减小窗口大小,通知发送方暂停发送,以防止溢出。
  • 动态调整: 发送方会根据接收方的窗口大小动态调整发送数据的速率。如果接收方的窗口大小增加,发送方可以加速发送数据。如果窗口大小减小,发送方将减缓发送数据的速率。

UDP如何实现可靠传输

UDP它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。关键在于两点,从应用层角度考虑:

(1)提供超时重传,能避免数据报丢失。

(2)提供确认序列号,可以对数据报进行确认和排序。

本端:首先在UDP数据报定义一个首部,首部包含确认序列号和时间戳,时间戳是用来计算RTT(数据报传输的往返时间),计算出合适的RTO(重传的超时时间)。然后以等-停的方式发送数据报,即收到对端的确认之后才发送下一个的数据报。当时间超时,本端重传数据报,同时RTO扩大为原来的两倍,重新开始计时。

对端:接受到一个数据报之后取下该数据报首部的时间戳和确认序列号,并添加本端的确认数据报首部之后发送给本端。根据此序列号对已收到的数据报进行排序并丢弃重复的数据报。

HTTP的keepalive和TCP的keepalive

  1. HTTPKeep-Alive,是由应用层实现的,称为 HTTP 长连接

每次请求都要经历这样的过程:建立 TCP连接 -> HTTP请求资源 -> 响应资源 -> 释放连接,这就是HTTP短连接,但是这样每次建立连接都只能请求一次资源,所以HTTP Keep-Alive实现了使用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,避免了连接建立和释放的开销,就就是 HTTP 长连接。通过设置HTTP头Connection: keep-alive来实现。

  1. TCPKeepalive,是由TCP 层(内核态)实现的,称为 TCP 保活机制,是一种用于在 TCP 连接上检测空闲连接状态的机制

TCP连接建立后,如果一段时间内没有任何数据传输,TCP Keepalive会发送探测包来检查连接是否仍然有效。

补充说明:

其实这里tcp的keepalive,不只是支持http,还可以支持ftp和smtp的,他是一个能力,类似于gc。

http的这个keepalive感觉更是一种策略吧,比如你有一个http用了keepalive,然后过了一会,你不传输数据了,这个时候没有通知对方close,这个时候tcp的keepalive就会起到用处去关闭这次链接。

CDN是什么

也就是内容分发网络,应对的问题是,服务器的用户可能分布在全球,那么访问服务器获取资源就需要经过多个节点的转发,带来一定时延.

CDN将内容存储在分布式的服务器上,使用户可以从距离较近的服务器获取所需的内容,从而加速互联网上的内容传输。

  • 就近访问:CDN 在全球范围内部署了多个服务器节点,用户的请求会被路由到距离最近的 CDN 节点,提供快速的内容访问。
  • 内容缓存:CDN 节点会缓存静态资源,如图片、样式表、脚本等。当用户请求访问这些资源时,CDN 会首先检查是否已经缓存了该资源。如果有缓存,CDN 节点会直接返回缓存的资源,如果没有缓存所需资源,它会从源服务器(原始服务器)回源获取资源,并将资源缓存到节点中,以便以后的请求。通过缓存内容,减少了对原始服务器的请求,减轻了源站的负载。
  • 可用性:即使某些节点出现问题,用户请求可以被重定向到其他健康的节点。

COOKIE和SESSION的区别

(1) Cookie和Session是什么?

Cookie Session 都用于管理用户的状态和身份, Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

  1. Cookie
  • 通常,服务器会将一个或多个 Cookie 发送到用户浏览器,然后浏览器将这些 Cookie 存储在本地。
  • 服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容
  1. Session

客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。Session 主要用于维护用户登录状态、存储用户的临时数据和上下文信息等。服务器为每个用户分配一个唯一的**Session ID**,通常存储在**Cookie**中。每个ID对应一个会话存储空间,存储用户在会话期间的状态和数据.

当用户与服务器交互时,服务器通过sessionid访问对应的会话存储空间,将数据如登陆状态,用户偏好等存储在会话中.

会话超时或者用户退出,导致服务器删除该会话数据

(2) Cookie和Session的区别?

  • 存储位置:Cookie 数据存储在用户的浏览器中,而 Session 数据存储在服务器上。
  • 数据容量:Cookie 存储容量较小,一般为几 KB。Session 存储容量较大,通常没有固定限制,取决于服务器的配置和资源。
  • 安全性:由于 Cookie 存储在用户浏览器中,因此可以被用户读取和篡改。相比之下,Session 数据存储在服务器上,更难被用户访问和修改。
  • 生命周期:Cookie可以设置过期时间,Session 依赖于会话的持续时间或用户活动。
  • 传输方式:Cookie 在每次 HTTP 请求中都会被自动发送到服务器,而 Session ID 通常通过 Cookie 或 URL 参数传递。