网络
从输入 URL 到页面加载完成的过程
- 在浏览器地址栏输入 URL
- 判断是否有永久重定向(301)
- 如果有,直接跳转到对应 URL
- 浏览器查看资源是否有强缓存,有则直接使用,如果是协商缓存则需要到服务器进行校验资源是否可用
- 检验新鲜通常有两个 HTTP 头进行控制
Expires和Cache-Control:- HTTP1.0 提供 Expires,值为一个绝对时间表示缓存新鲜日期
- HTTP1.1 增加了 Cache-Control: max-age=,值为以秒为单位的最大新鲜时间
- 检验新鲜通常有两个 HTTP 头进行控制
- 浏览器解析 URL获取协议,主机,端口,path
- 浏览器组装一个 HTTP(GET)请求报文
- DNS 解析,查找过程如下:
- 浏览器缓存
- 本机缓存
- hosts 文件
- 路由器缓存
- ISP DNS 缓存
- DNS 查询(递归查询 / 迭代查询)
- 端口建立 TCP 连接,三次握手如下:
- 客户端发送一个 TCP 的SYN=1,Seq=X的包到服务器端口
- 服务器发回SYN=1, ACK=X+1, Seq=Y的响应包
- 客户端发送ACK=Y+1, Seq=Z
- TCP 连接建立后发送 HTTP 请求
- 服务器接受请求并解析,将请求转发到服务程序,如虚拟主机使用 HTTP Host 头部判断请求的服务程序
- 服务器检查HTTP 请求头是否包含缓存验证信息如果验证缓存新鲜,返回304等对应状态码
- 处理程序读取完整请求并准备 HTTP 响应,可能需要查询数据库等操作
- 服务器将响应报文通过 TCP 连接发送回浏览器
- 浏览器接收 HTTP 响应,然后根据情况选择关闭 TCP 连接或者保留重用,关闭 TCP 连接的四次挥手如下:
- 主动方发送Fin=1, Ack=Z, Seq= X报文
- 被动方发送ACK=X+1, Seq=Z报文
- 被动方发送Fin=1, ACK=X, Seq=Y报文
- 主动方发送ACK=Y, Seq=X报文
- 浏览器检查响应状态吗:是否为 1XX,3XX, 4XX, 5XX,这些情况处理与 2XX 不同
- 如果资源可缓存,进行缓存
- 对响应进行解码(例如 gzip 压缩)
- 根据资源类型决定如何处理(假设资源为 HTML 文档)
- 解析 HTML 文档,构件 DOM 树,下载资源,构造 CSSOM 树,执行 js 脚本,这些操作没有严格的先后顺序,以下分别解释
- 构建 DOM 树:
- Tokenizing:根据 HTML 规范将字符流解析为标记
- Lexing:词法分析将标记转换为对象并定义属性和规则
- DOM construction:根据 HTML 标记关系将对象组成 DOM 树
- 解析过程中遇到图片、样式表、js 文件,启动下载
- 构建CSSOM 树:
- Tokenizing:字符流转换为标记流
- Node:根据标记创建节点
- CSSOM:节点创建 CSSOM 树
- 根据 DOM 树和 CSSOM 树构建渲染树:
- 从 DOM 树的根节点遍历所有可见节点,不可见节点包括:1)
script,meta这样本身不可见的标签。2)被 css 隐藏的节点,如display: none - 对每一个可见节点,找到恰当的 CSSOM 规则并应用
- 发布可视节点的内容和计算样式
- 从 DOM 树的根节点遍历所有可见节点,不可见节点包括:1)
- js 解析如下:
- 浏览器创建 Document 对象并解析 HTML,将解析到的元素和文本节点添加到文档中,此时document.readystate 为 loading
- HTML 解析器遇到没有 async 和 defer 的 script 时,将他们添加到文档中,然后执行行内或外部脚本。这些脚本会同步执行,并且在脚本下载和执行时解析器会暂停。这样就可以用 document.write()把文本插入到输入流中。同步脚本经常简单定义函数和注册事件处理程序,他们可以遍历和操作 script 和他们之前的文档内容
- 当解析器遇到设置了async属性的 script 时,开始下载脚本并继续解析文档。脚本会在它下载完成后尽快执行,但是解析器不会停下来等它下载。异步脚本禁止使用 document.write(),它们可以访问自己 script 和之前的文档元素
- 当文档完成解析,document.readState 变成 interactive
- 所有defer脚本会按照在文档出现的顺序执行,延迟脚本能访问完整文档树,禁止使用 document.write()
- 浏览器在 Document 对象上触发 DOMContentLoaded 事件。 DOMContentLoaded 事件表示 DOM 挂载完毕。
- 此时文档完全解析完成,浏览器可能还在等待如图片等内容加载,等这些内容完成载入并且所有异步脚本完成载入和执行,document.readState 变为 complete,window 触发 load 事件。 Load 事件表示所有资源加载完成。
- 显示页面(HTML 解析过程中会逐步显示页面)
浏览器的工作流程大致就是:构建 DOM 树-构建 CSSOM-构建渲染树-布局-绘制
HTTP 状态码
1xx: 指示信息 2xx: 成功 200 206 3xx: 重定向 301 永久重定向 302 临时重定向 304 缓存 4xx: 客户端错误 400 401 未授权 403 资源禁止被访问 404 资源不存在 5xx: 服务端错误 500 503
HTTP 方法
GET, POST, PUT, DELETE, HEAD. HEAD 方法用于获取报文首部
HTTP 报文的组成部分
http 就是建立在 tcp 连接之上的应用层, http 报文是由请求报文和相应报文组成的。
请求报文:
- 请求行。请求行包含 http 方法,页面地址,http 协议以及版本
- 请求头。 一些 key-value 值告诉服务端需要什么内容
- 空行。分离请求头和请求体
- 请求体
响应报文:
- 状态行
- 响应头
- 空行
- 响应体
POST 和 GET 的区别
- GET 在浏览器回退时是无害的,而 POST 会再次提交请求 (记)
- GET 产生的 URL 地址可以被收藏,而 POST 不可以
- GET 请求会被浏览器主动缓存,而 POST 不会,除非手动设置 (记)
- GET 请求只能进行 URL 编码,而 POST 支持多种编码方式
- GET 请求参数会被完整保存在浏览器的历史记录里,而 POST 中的参数不会被保留 (记) 为了防止 CSRF 攻击好多人都会把 GET 请求改成 POST 请求
- GET 请求在 URL 中传送的参数是有长度限制的(基本是 2 kb,不同浏览器不一样,因为 http 协议对长度是有限制的,会被截断),而 POST 没有限制 (记)
- 对参数的数据类型,GET 只接受 ASCII 字符,而 POST 没有限制
- GET 比 POST 更不安全,因为参数直接暴露在 URL 上,所以不能用来传入敏感信息
- GET 参数通过 URL 传递,POST 放在 Request Body 中 (记)
三次握手和四次挥手
简述
三次握手:
- A 发送 SYN = x 给 B. A 进入 SYN_SEND
- B 发动 ACK = x + 1, SYN = y 给 A. B 进入 SYN_RECEIVED
- A 发送 ACK = y + 1 给 B. A,B 进入 ESTABLISHED
四次挥手:
- A 发送 FIN = x 给 B. A 进入 FIN_WAIT_1
- B 发动 ACK = x + 1 给 A. B 进入 CLOSE_WAIT, A 收到 ACK 之后进入 FIN_WAIT_2
- B 发动 FIN = y 给 A. B 进入 LAST_ACK
- A 发送 ACK = y + 1 给 B. A 进入 TIME_WAIT, B 收到 ACK 之后进入 CLOSED
详细
在开始之前,先简单说一下 TCP 连接中比较常用的五个状态:
SYN表示建立连接FIN表示关闭连接ACK表示响应PSH表示 data 数据传输RST表示连接重置
其中 ACK 是可能与 SYN , FIN 等同时使用的, 比如 SYN 和 ACK 可能同时为 1, 它表示的就是建立连接之后的响应;如果只是单个的一个 SYN,表示的只是建立连接。TCP 的几次握手就是通过这样的 ACK 表现出来的。
但是 SYN 与 FIN 不会同时为 1,因为前者表示的是建立连接,后者表示的是断开连接。RST 一般是在 FIN 之后才会出现 1 的情况,表示重新连接。一般出现 FIN 包或者 RST 包时,我们就认为客户端与服务端断开了连接;当出现 SYN 和 SYN + ACK 包时, 我们就认为客户端和服务器建立了一个连接。RSH 为 1 的情况一般只出现在 data 内容不为 0 的包中,也就是说 PSH 为 1 表示的是真正有 TCP 数据包内容被传输。
TCP 的连接建立和连接关闭,都是通过请求-响应的模式完成的。
位码是 tcp 的标志位,标识:
- Sequence number 顺序号码
- Acknowledge number 确认号码
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP 连接一旦建立,在通信双方中的任何一动关闭连接之前,TCP 连接都将被一直保持下去。
过程
- 第一次握手:建立连接时,客户端发送 syn 包(syn=j) 到服务器,并进入 SYN_SEND 状态,等待服务器确认。
- 第二次握手:服务器收到 syn 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECEIVED 状态;
- 第三次握手:客户端收到服务器的 SYN + ACK 包,向服务器发送确认包 ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态(已建立),完成三次握手。完成三次握手,客户端与服务器开始传送数据.
完成三次握手之后,主机 A 与主机 B 就开始传输数据。
为什么要进行三次握手
- 在第一次通信过程中,A 向 B 发送信息之后,B 收到信息后可以确认自己的收信能力和 A 的发信能力没有问题。
- 在第二次通信中,B 向 A 发送信息之后,A 可以确认自己的发信能力和 B 的收信能力没有问题,但是 B 不知道自己的发信能力到底如何,所以就需要第三次通信。
- 在第三次通信中,A 向 B 发送信息之后,B 就可以确认自己的发信能力没有问题。
两次不够,四次没必要。
TCP 三次握手
- 客户端发送一个 syn(同步)包(syn=x)给服务器,进入 SYN_SEND 状态,等待服务器确认
- 服务端收到客户端发送的同步包,确认客户端的同步请求(ack=x+1),同时也发送一个同步包,也就是一个 ACK 包+SYN 包服务器进入 SYN_RECV 状态
- 客户端收到服务器的 SYN+ACK 包,向服务器发送一个确认包,此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手
不是两次是为了防止已经失效的连接请求报文段突然又传送到了服务端,因而产生错误,比如有一个因网络延迟的请求发送到了服务端,服务端收到这个同步报文之后进行确认,如果此时是两次握手,那么此时连接建立,但是客户端并没有发出建立连接的请求,服务端却一直等待客户端发送数据,这样服务端的资源就白白浪费了。
不是四次的话是因为完全没有必要,三次已经足够了
TCP 四次挥手
- 主动关闭方发送一个 FIN 包,用来关闭主动关闭方到被动关闭方的数据传送,也就是告诉另一方我不再发送数据了,但此时仍可以接收数据
- 被动关闭方收到 FIN 包之后,发送一个确认(ACK)包给对方,确认序号为收到序号+1(与 SYN 相同,一个 FIN 占用一个序号)
- 被动关闭方发送一个 FIN 包,告诉对方不再发送数据
- 主动关闭方收到 FIN 包之后,发送一个 ACK 包给对方,确认序号为收到序号+1,至此完成四次挥手
四次挥手
TCP 是全双工的,在断开连接时两端都需要发送 FIN 和 ACK。
- 第一次挥手:主动关闭方发送一个
FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不 会再给你发数据了(当然,在 fin 包之前发送出去的数据,如果没有收到对应的 ack 确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可 以接受数据。发送完毕后,客户端进入FIN_WAIT_1状态。 - 第二次挥手:被动关闭方收到
FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。发送完毕后,服务器端进入CLOSE_WAIT状态,客户端接收到这个确认包之后,进入FIN_WAIT_2状态,等待服务器端关闭连接。 - 第三次挥手:被动关闭方发送一个
FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。发送完毕后,服务器端进入LAST_ACK状态,等待来自客户端的最后一个 ACK。 - 第四次挥手:主动关闭方收到
FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入TIME_WAIT状态,等待可能出现的要求重传的 ACK 包。服务器端接收到这个确认包之后,关闭连接,进入CLOSED状态。客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入CLOSED状态。
网络分层
- 物理层
- 数据链路层
- 网络层(IP)
- 传输层(TCP)
- 应用层(Http)
大网络分层
OSI 分层 (7 层):物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 TCP/IP 分层(4 层):网络接口层、 网际层、运输层、 应用层。 五层协议 (5 层):物理层、数据链路层、网络层、运输层、 应用层。
CDN
CDN(Content Delivery Network,内容分发网络)是构建在现有互联网基础之上的一层智能虚拟网络,通过在网络各处部署节点服务器,实现将源站内容分发至所有 CDN 节点,使用户可以就近获得所需的内容。CDN 服务缩短了用户查看内容的访问延迟,提高了用户访问网站的响应速度与网站的可用性,解决了网络带宽小、用户访问量大、网点分布不均等问题。
CDN 主要有以下优点:
- 更快地将数据分发给用户;
- 通过部署多台服务器,从而提高系统整体的带宽性能;
- 多台服务器可以看成是一种冗余机制,从而具有高可用性。
加速原理
当用户访问使用 CDN 服务的网站时,本地 DNS 服务器通过 CNAME 方式将最终域名请求重定向到 CDN 服务。CDN 通过一组预先定义好的策略(如内容类型、地理区域、网络负载状况等),将当时能够最快响应用户的 CDN 节点 IP 地址提供给用户,使用户可以以最快的速度获得网站内容。使用 CDN 后的 HTTP 请求处理流程如下:
CDN 的核心功能
CDN 的核心点有两个,一个是缓存,一个是回源。
- “缓存”就是说我们把资源 copy 一份到 CDN 服务器上这个过程
- “回源”就是说 CDN 发现自己没有这个资源(一般是缓存的数据过期了),转头向根服务器(或者它的上层服务器)去要这个资源的过程。
CDN 节点有缓存场景
- 用户在浏览器输入要访问的网站域名,向本地 DNS 发起域名解析请求。
- 域名解析的请求被发往网站授权 DNS 服务器。
- 网站 DNS 服务器解析发现域名已经 CNAME 到了 www.example.com.c.cdnhwc1.com。
- 请求被指向 CDN 服务。
- CDN 对域名进行智能解析,将响应速度最快的 CDN 节点 IP 地址返回给本地 DNS。
- 用户获取响应速度最快的 CDN 节点 IP 地址。
- 浏览器在得到速度最快节点的 IP 地址以后,向 CDN 节点发出访问请求。
- CDN 节点将用户所需资源返回给用户。
为什么传统上利用多个域名来提供网站资源会更有效?
- CDN 缓存更方便
- 突破浏览器并发限制(一般每个域名建立的链接不超过 6 个)
- Cookie less,节省带宽,尤其是上行带宽一般比下行要慢
- 对于 UGC 的内容和主站隔离,防止不必要的安全问题(上传 js 窃取主站 cookie 之类的)。正是这个原因要求用户内容的域名必须不是自己主站的子域名,而是一个完全独立的第三方域名。
- 数据做了划分,甚至切到了不同的物理集群,通过子域名来分流比较省事。这个可能被用的不多
关于 Cookie 的问题,带宽是次要的,安全隔离才是主要的。关于多域名,也不是越多越好,虽然服务器端可以做泛解释,浏览器做 dns 解释也是耗时间的,而且太多域名,如果要走 https 的话,还有要多买证书和部署的问题
CDN 服务器域名与业务服务器域名不一致。将静态资源放在其他域名,在请求这些静态资源的时候不会发送 cookie,节省了流量,需要注意的是 cookie 是会发送给子域名的(二级域名),所以这些静态资源是不会放在子域名下的,而是单独放在一个单独的主域名下。同时还有一个原因就是浏览器对于一个域名会有请求数的限制,这种方法可以方便做 CDN。
DNS
请描述一下 DNS 解析的具体过程?
DNS 的作用就是通过域名查询到具体的 IP。
因为 IP 存在数字和英文的组合(IPv6),很不利于人类记忆,所以就出现了域名。你可以把域名看成是某个 IP 的别名,DNS 就是去查询这个别名的真正名称是什么。
在 TCP 握手之前就已经进行了 DNS 查询,这个查询是操作系统自己做的。当你在浏览器中想访问 www.google.com 时,会进行一下操作:
- 操作系统会首先在本地缓存中查询
- 没有的话会去系统配置的 DNS 服务器中查询
- 如果这时候还没得话,会直接去 DNS 根服务器查询,这一步查询会找出负责
com这个一级域名的服务器 - 然后去该服务器查询
google这个二级域名 - 接下来三级域名的查询其实是我们配置的,你可以给
www这个域名配置一个 IP,然后还可以给别的三级域名配置一个 IP
以上介绍的是 DNS 迭代查询,还有种是递归查询,区别就是前者是由客户端去做请求,后者是由系统配置的 DNS 服务器做请求,得到结果后将数据返回给客户端。
PS:DNS 是基于 UDP 做的查询。
DNS 域名系统,简单描述其工作原理。
DNS 客户机需要在程序中使用名称时,它会查询 DNS 服务器来解析该名称。客户机发送的每条查询信息包括三条信息:包括:指定的 DNS 域名,指定的查询类型,DNS 域名的指定类别。基于 UDP 服务,端口 53. 该应用一般不直接为用户使用,而是为其他应用服务,如 HTTP,SMTP 等在其中需要完成主机名到 IP 地址的转换。
TCP
TCP(Transmission Control Protocol),又叫传输控制协议。TCP 协议是面向连接的,可靠的,基于字节流的传输协议。在基于 TCP 进行通信时,通信双方需要先建立一个 TCP 连接,建立连接需要经过三次握手,断开连接的时候需要经过四次挥手。
简介
- TCP 提供一种面向连接的、可靠的字节流服务
- 在一个 TCP 连接中,仅有两方进行彼此通信。广播和多播不能用于 TCP
- TCP 使用校验和,确认和重传机制来保证可靠传输
- TCP 给数据分节进行排序,并使用累积确认保证数据的顺序不变和非重复
- TCP 使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制
注意:TCP 并不能保证数据一定会被对方接收到,因为这是不可能的。TCP 能够做到的是,如果有可能,就把数据递送到接收方,否则就(通过放弃重传并且中断连接这一手段)通知用户。因此准确说 TCP 也不是 100% 可靠的协议,它所能提供的是数据的可靠递送或故障的可靠通知。
使用场景
TCP 对应的协议:
- FTP:定义了文件传输协议,使用 21 端口。
- Telnet:一种用于远程登陆的端口,使用 23 端口,用户可以以自己的身份远程连接到计算机上,可提供基于 DOS 模式下的通信服务。
- SMTP:邮件传送协议,用于发送邮件。服务器开放的是 25 号端口。
- POP3:它是和 SMTP 对应,POP3 用于接收邮件。POP3 协议所用的是 110 端口。
- HTTP:是从 Web 服务器传输超文本到本地浏览器的传送协议。
UDP
简介
UDP 是一个简单的传输层协议。 UDP 又叫用户数据报协议。UDP 是一个无连接的、不可靠、基于数据报的传输协议。UDP 是不需要和 TCP 一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了。
特点:
- 面向报文
- 不可靠传输
- 高效
和 TCP 相比,UDP 有下面几个显著特性:
- UDP 缺乏可靠性。UDP 本身不提供确认,序列号,超时重传等机制。UDP 数据报可能在网络中被复制,被重新排序。即 UDP 不保证数据报会到达其最终目的地,也不保证各个数据报的先后顺序,也不保证每个数据报只到达一次
- UDP 数据报是有长度的。每个 UDP 数据报都有长度,如果一个数据报正确地到达目的地,那么该数据报的长度将随数据一起传递给接收方。而 TCP 是一个字节流协议,没有任何(协议上的)记录边界。
- UDP 是无连接的。UDP 客户和服务器之前不必存在长期的关系。UDP 发送数据报之前也不需要经过握手创建连接的过程。
- UDP 支持多播和广播。
概述
- UDP 相比 TCP 简单的多,不需要建立连接,不需要验证数据报文,不需要流量控制,只会把想发的数据报文一股脑的丢给对端
- 虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为
1. 面向报文
UDP 是一个面向报文(报文可以理解为一段段的数据)的协议。意思就是 UDP 只是报文的搬运工,不会对报文进行任何拆分和拼接操作。
具体来说
- 在发送端,应用层将数据传递给传输层的 UDP 协议,UDP 只会给数据增加一个 UDP 头标识下是 UDP 协议,然后就传递给网络层了
- 在接收端,网络层将数据传递给传输层,UDP 只去除 IP 报文头就传递给应用层,不会任何拼接操作
2. 不可靠性
- UDP 是无连接的,也就是说通讯不需要建立和断开链接。
- UDP 是不可靠的。它不会去备份数据,也不关心对方是否能收到数据。
- UDP没有拥塞控制,一直以恒定的速度发送数据,即使网络条件不好,也不进行速率调整。 造成的弊端就是在网络条件不好时可能导致丢包。
3. 高效性
因为 UDP 没有 TCP 那么复杂,不需要保证数据不丢失且有序到达。所以 UDP 的头部开销小,只有八字节,相比 TCP 的至少二十字节要少得多,在传输数据报文时是很高效的。
UDP 包头部包含了以下几个数据
- 两个十六位的端口号,分别为源端口(可选字段)和目标端口
- 整个数据报文的长度
- 整个数据报文的检验和(IPv4 可选 字段),该字段用于发现头部信息和数据中的错误
使用场景
UDP 虽然对比 TCP 有很多缺点,但是正是因为这些缺点造就了它高效的特性,在很多实时性要求高的地方都可以看到 UDP 的身影。 当强调输出性能而非完整性时,如音频和多媒体的实时传输。视频流传输协议 RTP 的实时传输就是基于 UDP 封装而来的。
UDP 对应的协议:
- DNS:用于域名解析服务
- SNMP:简单网络管理协议,使用 161 号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。
- TFTP(Trival File Transfer Protocal),简单文件传输协议,该协议在熟知端口 69 上使用 UDP 服务。
http 与 tcp 的关系
tcp 可以建立多个连接吗
TCP 和 UDP 的区别?
TCP 基本是和 UDP 反着来,建立连接断开连接都需要先需要进行握手。在传输数据的过程中,通过各种算法保证数据的可靠性,当然带来的问题就是相比 UDP 来说不那么的高效。
TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个 TCP 连接必须要经过三次“对话”才能建立起来
UDP(User Data Protocol,用户数据报协议)是与 TCP 相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去。 UDP 适用于一次只传送少量数据、对可靠性要求不高的应用环境。
- TCP 是面向连接的,udp 是无连接的即发送数据前不需要先建立链接。
- TCP 提供可靠的服务。也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付。 并且因为 TCP 可靠,面向连接,不会丢失数据因此适合大数据量的交换。
- TCP 是面向字节流,UDP 面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如 IP 电话和视频会议等)。
- TCP 只能是 1 对 1 的,UDP 支持 1 对 1,1 对多。
- TCP 的首部较大为 20 字节,而 UDP 只有 8 字节。
- TCP 是面向连接的可靠性传输,而 UDP 是不可靠的。
HTTP 与 TCP 的联系
HTTP 协议是建立在 TCP 协议之上的一种应用。
UDP 和 TCP 的特点
用户数据报协议 UDP(User Datagram Protocol)是无连接的,尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多的交互通信。
传输控制协议 TCP(Transmission Control Protocol)是面向连接的,提供可靠交付,有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条 TCP 连接只能是点对点的(一对一)。
持久连接 Keep-Alive
我们知道 HTTP 协议采用“请求-应答”模式,当使用普通模式,即非 Keep-Alive 模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP 协议为无连接的协议);当使用 Keep-Alive 模式(又称持久连接、连接重用)时,Keep-Alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive 功能避免了建立或者重新建立连接。
http 1.1 之后支持
gzip
Nginx 的 ngx_http_gzip_module 也提供了开启 GZIP 压缩的方式。一般会在 nginx 开启 gzip 来压缩静态资源的体积。开启成功之后,network 里显示文件体积会显示两个,一般能将源文件压缩到 1/3 大小。
浏览器在请求资源的时候再 header 里面带上 accept-encoding: gzip 的参数。Nginx 在接收到 Header 之后,发现如果有这个配置,则发送 GZIP 之后的文件(返回的 header 里也包含相关的说明),如果没有则发送源文件。浏览器根据 response header 来处理要不要针对返回的文件进行解压缩然后展示。
原理
首先使用 LZ77 算法的一个变种进行压缩,对得到的结果再使用 Huffman 编码的方法(实际上 gzip 根据情况,选择使用静态 Huffman 编码或者动态 Huffman 编码,详细内容在实现中说明)进行压缩。