究极深入Android网络优化——网络筑基(一)

前言

网络优化一直被认为是移动优化水最深的领域之一,因此要想对网络进行深入优化,我们就必须先打下比较扎实的网络基础,在本文中,我们将再次重温计算机网络中的重点知识,以此在脑海中建立一个较为全面的网络基础知识体系。

大纲

究极深入Android网络优化——网络筑基(一)_第1张图片

一、重识计算机网络

1、计算机网络是什么?

  • 1)、主要由 「通用、可编程的硬件互连」 而成。
  • 2)、通过这些硬件,可以 「传送不同类型的数据」
  • 3)、计算机网络不仅包含 「软件概念」,还包含 「硬件设备」
  • 4)、计算机网络不仅仅是 「信息通信」,还可以 「支持广泛和日益增长的应用」

2、计算机网络的分类

1)、按作用范围

广域网(WAN)

几十 KM ~ 几千 KM,跨省、跨国。

城域网(MAN)

5 KM ~ 50 KM,城市间、城市内。

局域网(LAN)

1 KM 内,地区内、家庭间、公司内。

2)、按网络使用者

公用网络

所有可以通过付费方式就可以加入的网络。

专用网络

某些部队、组织或者某些人 「为了满足特殊业务需求而建立起来的特殊的网络」,例如军队、铁路、银行都有自己的专用网络。

二、网络历史演进

1、世界互联网发展历史演进

1)、单个网络

「ARPANET」,1969年美国国防部创建的一个网络,可以连接周围的计算机。

计算机直接通过交换机就可以进行信息交换。

究极深入Android网络优化——网络筑基(一)_第2张图片

2)、三级结构

「现代互联网的雏形」,也称为 「互联网络」,可以把美国所有的大学、研究所、实验室都连接起来。

从上至下,由 「主干网、地区网、校园网」 组成。

究极深入Android网络优化——网络筑基(一)_第3张图片

3)、多层次 ISP

ISP(Internet Service Provider):网络服务提供商,例如中国电信、中国移动、中国联通等。「从上之下,由主干 ISP、地区 ISP 组成」

主干 ISP

中国的主干 ISP 包括 「中国电信、中国移动、中国联通」,它们可以连接美国和其它国家的主干 ISP。

地区 ISP

例如移动网络,在北京叫 「北京移动」,在上海叫 「上海移动」,这些就属于地区 ISP。「地区 ISP 可以连接公司、校园、家庭的网络」

究极深入Android网络优化——网络筑基(一)_第4张图片

4)、了解现代国际互联网的主要线路

我们可以通过 infrapedia 网站了解国际互联网的主要线路。

究极深入Android网络优化——网络筑基(一)_第5张图片

上图刻画了 「全球的所有主干网络的线路」,可以看到,「中国的主干网络出口基本都是位于广东、福建等沿海地区,它们通过各自的海底电缆与位处于世界各地的主干网络相互连接,最终形成了互联网」

2、中国互联网发展历史

1)、1980 年

中国铁道部开始互联网实验。

2)、1989 年

建立并运行第一个公共网络。

3)、1994 年

接入国际互联网。

4)、至今

「当今中国最大的五个公用的计算机网络」

  • 「中国电信互联网(CHINANET)」
  • 「中国联通互联网(UNINET)」
  • 「中国移动互联网(CMNET)」
  • 「中国教育与科研计算机网(CERNET)」
  • 「中国科学技术网(CSTNET)」

3、中国的互联网企业

  • 1996年,张朝阳创建搜狐。
  • 1997年,丁磊创建网易。
  • 1998年,王志东创建新浪,马化腾、张志东创建腾讯。
  • 1999年,马云创建阿里巴巴。
  • 2000年,李彦宏创建百度。

三、重识网络层次结构

网络为什么要分层?

因为复杂的程序都要分层。这是一个架构设计的通用问题,不仅仅是网络协议的问题,「只要涉及复杂的逻辑或软件需求需要经常变动的情况通常都会通过分层来解决」

思考:设计一个计算机网络需要解决哪些问题?

  • 1)、传输数据时需要保证数据通路顺畅。
  • 2)、需要识别目的计算机。
  • 3)、需要了解目的计算机的状态。
  • 4)、数据是否错误。

总之,计算机网络需要解决的问题是繁多而复杂的,所以我们需要 「采用分层的设计分别去解决不同的问题,实现不同的功能」

1、层级结构设计的基本原则

1)、相互独立

每一层仅仅实现一个相对独立的功能,并且需要确保层与层之间的耦合度是非常低的。

2)、灵活性

每一层的设计需要具备很好的灵活性、扩展性,以适应未来的网络变化。

3)、耦合度

各层之间是完全解耦的,层与层之间的变化互不影响。

2、OSI 七层模型

OSI 功能
应用层 为计算机用户提供接口和服务。
表示层 数据处理:编解码、加解密等等。
会话层 管理(建立、维护、重连)通信会话。
传输层 管理端到端的通信连接。
网络层 数据路由:决定数据在网络中的路径。
数据链路层 管理相邻节点之间的数据通信。
物理层 数据通信的光电物理特性。

究极深入Android网络优化——网络筑基(一)_第6张图片

1)、OSI 悲催的故事

  • 1)、一开始,OSI 欲称为全球计算机都遵守的标准。
  • 2)、但是,OSI 在市场化的过程中困难重重,因为 TCP/IP 已经在全球范围成功运行。
  • 3)、最终,OSI 并没有称为广为使用的标准模型。

2)、OSI 七层模型失败的原因

  • 1)、OSI 的专家没有充分将理论与实际进行结合。
  • 2)、OSI 标准的制定周期过长,按 OSI 标准生产的设备无法及时进入市场。
  • 3)、OSI 模型的设计不合理,某些功能在多层重复出现。

3、TCP/IP 四层模型

究极深入Android网络优化——网络筑基(一)_第7张图片

我们需要理解数据通信过程中不同设备之间协议的转换。从下图可以看到 「路由器仅包括网络层与网络接口层」

究极深入Android网络优化——网络筑基(一)_第8张图片

从协议的数量来看,TCP/IP 四层模型构成了中间窄,两端大的⏳沙漏形状。如下图所示:

究极深入Android网络优化——网络筑基(一)_第9张图片

四、初识现代网络拓扑

1、为什么要了解网络拓扑?

因为它 「有助于我们在脑海里面形成一个形象的计算机网络」

2、网络拓扑分类

1)、边缘部分

家庭

「终端机器、路由器、网关、地区 ISP」 组成。

究极深入Android网络优化——网络筑基(一)_第10张图片

企业

不同于家庭的网络拓扑,其 「网关细分为内部网关与统一网关」

究极深入Android网络优化——网络筑基(一)_第11张图片

2)、核心部分

「地区 ISP、主干 ISP、路由器、海底电缆或跨地区电缆」 组成。其中的 「通信设备(一般是华为)主要是由移动、联通所铺设的」

究极深入Android网络优化——网络筑基(一)_第12张图片

现代互联网的网络拓扑形成了一个 「树状结构」

究极深入Android网络优化——网络筑基(一)_第13张图片

3)、C/S 模式

由 客户端/服务端 模式组成,并可以相互进行通信。

究极深入Android网络优化——网络筑基(一)_第14张图片

4)、P2P 模式

不分为服务端和客户端,它们都是 「对等地进行连接的」,优势在于可以使 「下载速度更快」,如迅雷下载器中就应用了这种模式。

究极深入Android网络优化——网络筑基(一)_第15张图片

五、网络性能指标

1、速率

即 bps <==> bit/s

网络数据传输的各种单位与之对应的常见设备

究极深入Android网络优化——网络筑基(一)_第16张图片

为什么电信拉的 100M 光纤,测试峰值速度只有 12M 每秒?

网络常用单位为(Mbps),因此这里的 100M 指的是 100Mbps。

100 M/S = 100 Mbps = 100 Mbit/s
100 Mbit/s = (100/8)MB/s = 12.5 MB/s 

2、时延

1)、发送时延

发送时延 = 数据长度(bit)/ 发送速率(bit/s)

数据长度是由用户决定的,而发送速率是由计算机网卡所决定的。

2)、传输时延

传播时延 = 传输路径距离 / 传播速率(bit/s)

传输路径距离是由用户决定的,而传播速率则受限于传输介质。

3)、排队时延

数据包在网络设备中等待被处理的时间,例如路由器需要一个一个处理完前面的数据包才能处理后面的。

4)、处理时延

数据包到达设备或者目的机器被处理所需的时间。

总时延 = 发送时延 + 排队时延 + 传播时延 + 处理时延

3、往返时间 RTT(Route-Trip Time)

  • 评估网络质量的一项重要指标。
  • 表示数据报文在端到端通信中来回一次的时间。

通常使用 ping 命令查看 RTT

1)、ping 查看当前城市中的 IP

quchao@quchaodeMacBook-Pro ~ % ping 119.29.148.149
PING 119.29.148.149 (119.29.148.149): 56 data bytes
64 bytes from 119.29.148.149: icmp_seq=0 ttl=116 time=13.210 ms
64 bytes from 119.29.148.149: icmp_seq=1 ttl=116 time=19.118 ms
64 bytes from 119.29.148.149: icmp_seq=2 ttl=116 time=34.384 ms 

2)、ping 美国的 IP

quchao@quchaodeMacBook-Pro ~ % ping 191.101.238.160
PING 191.101.238.160 (191.101.238.160): 56 data bytes
64 bytes from 191.101.238.160: icmp_seq=0 ttl=52 time=191.791 ms
64 bytes from 191.101.238.160: icmp_seq=1 ttl=52 time=180.278 ms
64 bytes from 191.101.238.160: icmp_seq=2 ttl=52 time=186.399 ms 

六、应用层

「传输层与之下的层已经提供了完整的通信服务」。而应用层是面向用户的一层。它主要是用来 「定义应用间通信的规则」,例如应用进程的报文类型(请求报文、应答报文)、报文的语法、格式、应用进程发送数据的时机、规则等等。

1、DNS(Domain Name System) 域名系统服务

域即对应的网络号,名即对应的主机名字。

1)、功能

通过把没有规则的点分十进制 IP 地址转换为可以理解的一些域名。

2)、域名

  • 使用域名可以帮助记忆。
  • 域名通过 DNS 服务可以被转换成 IP 地址。
  • 域名是由点、字母和数字组成的。
  • 点分割不同的域。
  • 「域名可以分为顶级域、二级域、三级域…,例如:www.taobao.com => - 三级域.二级域.顶级域」

顶级域常见分类

  • 国家

    • cn
    • us
    • uk
    • ca
  • 通用

    • com
    • net
    • gov
    • org

二级域

例如:qq、aliyun、taobao、google、facebook 等等。

「顶级域、二级域、三级域组成了一个树状结构。且在顶级域名服务器上面还有一个根域名服务器」

3)、域名服务器

只要有一个外网的服务器就可以搭建一个域名的服务器。

2、DHCP(Dynamic Host Configuratin Protocol) 动态主机设置协议

1)、是什么?

「网络管理员只需配置一段共享的 IP 地址,每一台新接入的机器都可以通过 DHCP 来这个共享的 IP 地址里面申请 IP 地址,就可以自动配置。等用完还回去其它机器也能使用」。它的特点如下所示:

  • 1、「DHCP 是一个局域网协议」
  • 2、「DHCP 是应用 UDP 协议的应用层协议」

2)、功能

  • 「即插即用联网」
  • 「在 IP 配置界面选中 自动获得 IP 地址、自动获得 DNS 服务器地址即可启用 DHCP 协议去获取一个临时 IP(通常是一个内网地址)」
  • 「有一个租期,在租期过半时可以续租」

3)、DHCP 的过程

  • 1)、「DHCP 服务器监听默认端口:67」
  • 2)、「主机使用 UDP 协议广播 DHCP 发现报文」
  • 3)、「DHCP 服务器发出 DHCP 提供报文」
  • 4)、「主机向 DHCP 服务器发出 DHCP 请求报文」
  • 5)、「DHCP 服务器回应并提供 IP 地址」

4)、向 DHCP 租用的 IP 地址是有租期的,IP 地址如何实现续租呢?

客户端会在租期过去50%的时候,直接向为其提供 IP 地址的 DHCP 服务器发送 DHCP request 消息报。客户端接收到服务器回应的 DHCP ACK 消息包后,会根据消息报中提供的新的租期以及其他已经更新的 TCP/IP 参数更新自己的配置。

3、HTTP(HyperText Tranfsfer Protocol) 超文本传输协议

1)、是什么?

  • HyperText 即超文本、超链接,Http 是指在电脑中显示的、「含有可以指向其他文本的链接文本」
  • 对于这些内容都有一个统一的路径,例如: http(s)://<主机>:<端口>/<路径>
  • 「HTTP 协议底层是 TCP 协议,因此它是可靠的数据传输协议」

2)、Web 服务器

分为硬件部分(计算机或云上的虚拟设备)和软件部分(Nginx、Apache)。

过程

  • 1)、「接受客户端连接」
  • 2)、「接受请求报文」
  • 3)、「处理请求」
  • 4)、「访问 Web 资源」
  • 5)、「构造应答」
  • 6)、「发送应答」

3)、HTTP 请求方法

header 1 header 2
GET 获取指定的服务端资源。
POST 提交数据到服务端。
DELETE 删除指定的服务端资源。(很少用)
UPDATE 更新指定的服务端资源。
PUT 修改数据。
OPTIONS 列出可对资源实行的请求方法,用来跨域请求。
CONNECT 建立连接隧道,用于代理服务器
HEAD 获取资源的元信息
TRACE 追踪请求-响应的传输路径

GET 和 POST 的区别

  • 1、「get参数通过url传递,post放在request body中」
  • 2、「get请求在url中传递的参数是有长度限制的,而post没有」
  • 3、「get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息」
  • 4、「get请求只能进行url编码,而post支持多种编码方式」
  • 5、「get请求会浏览器主动cache,而post支持多种编码方式」
  • 6、「get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留」
  • 7、「GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同」

4)、HTTP 指定资源

1)、在地址中指定

https://www.wanandroid.com/repo/100.html

repo/100.html 是指定的请求资源。

https://www.wanandroid.com/?sort=0&unlearn=0&page=2

? 后面用来指定请求参数。

2)、在请求数据中指定

5)、HTTP 请求报文

HTTP 的请求报文与响应报文都满足如下结构:

起始行 + 头部 + 空行 + 实体

其中的 「空行是用来区分开头部和实体的」

HTTP 请求报文的格式如下所示:

究极深入Android网络优化——网络筑基(一)_第17张图片

例如:

POST https://www.wanandroid.com HTTP/1.1
Accept-Encoding:gzip
Accept-Language:zh-CN
...
{ 请求的 jsonString 内容} 

6)、HTTP 应答报文

究极深入Android网络优化——网络筑基(一)_第18张图片

7)、HTTP 应答状态码

header 1 header 2
100~199 协议处理的中间状态,还需要后续操作
200~299 成功
300~399 重定向
400~499 客户端错误
500~599 服务端错误

100~199

  • 101:Switching Protocols,服务器同意将 HTTP 升级为 WebSocket 时发送。

200~299

  • 200:在响应体中放有数据。
  • 204:No Content,响应头后没有 body 数据。
  • 206:Partial Content,通常用于 HTTP 分块下载和断点续传,同时带上相应的响应头字段 Content-Range。

300~399

  • 301:Moved Permanently,永久重定向。
  • 302:Found,临时重定向。
  • 304:Not Modified,协商缓存命中时返回。

400~499

  • 400:Bad Request,请求出错。
  • 403:Forbidden,服务器禁止访问,原因有法律禁止、信息敏感等。
  • 404:Not Found,资源未找到。
  • 405:Method Not Allowed,请求方法不被允许。
  • 406:Not Acceptable,资源无法满足条件。
  • 408:Request Timeout,请求超时。
  • 409:Conflict,多个请求发生了冲突。
  • 413:Request Entity Too Large,请求体的数据过大。
  • 414:Request-URI Too Long,请求行里的 URI 太大。
  • 429:Too Many Request,客户端发送的请求过多。
  • 431:Request Header Fields Too Large,请求头的字段内容太大。

500~599

  • 500:Internal Server Error,服务内部出错。
  • 501:Not Implemented: 请求的功能不支持。
  • 502:Bad Gateway: 服务器自身是正常的,只是数据通道有问题。
  • 503:Service Unavailable: 服务器很忙,无法响应服务。

8)、HTTP 工作结构

Web 缓存

通常遵循 「二八原则」:一个网站的内容通常分为20%的热门内容,80%的冷门内容。因此可以优先缓存热门内容。

存储器层次结构

缓存(CPU 高速缓存)/主存(内存)/辅存(磁盘)

Web 代理

  • 通过 Web 代理可以屏蔽服务器的部署结构。
  • 可以在 Web 代理里面设置规则,如防火墙来保证安全。
Web 代理的分类
  • 1)、正向代理:代理客户端去访问 Server。
  • 2)、反向代理:代理 Server 把数据返回给客户端。例如 Nginx、HAProxy 就是一些著名的代理软件。

CDN(Content Delivery Network)内容分发网络

  • 「用于将一些大的内容在临近的服务器留一个备份」
  • 「使用 CDN 可以进行多媒体内容的加速」

CDN的基本原理是 「广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应」

爬虫

用于在互联网上采集信息, 例如百度、Google的本质就是一个爬虫,它们通过把整个网络的数据给取下来,并且做一个索引,然后把这些内容提供给大家,在进行搜索时就会匹配这些内容并返回。

不好的爬虫的缺点:
  • 增加网络拥塞。
  • 损耗服务器资源。

4、HTTPS(Secure) 安全的 HTTP 协议

https://<主机>:<443>/<路径>

HTTP 是明文传输的,但是我们需要在网络中传输 账号密码、个人信息、账号金额、交易信息、敏感信息,这会导致中间人非法截取信息,导致信息泄露。

1)、加密模型

  • 「对称加密:加密与解密都使用同一个秘钥」

  • 「非对称加密:公钥加密,私钥解密,并且公钥与私钥是拥有一定数学关系的一组秘钥」

    • 「私钥:自己使用,不对外公开」
    • 「公钥:给大家使用,对外公开」

2)、数字证书 签名校验

「数字证书是可信任组织颁发给特定对象的认证。而可信任组织即客户端与服务端都认为安全的组织」

数字证书格式

  • 证书格式、版本号
  • 证书序列号
  • 签名算法
  • 有效期
  • 对象名称
  • 对象公开秘钥

3)、SSL(Secure Sockets Layer)安全套接层

「SSL 位于传输层与应用层之间,它是一个子层,作用主要有两点」

  • 1)、「数据安全(保证数据不会被泄漏)与数据完整(保证数据不会被篡改)」
  • 2)、「对数据进行加密后传输」

HTTPS 的通信过程

  • 1)、「443 端口的 TCP 连接」
  • 2)、「SSL 安全参数握手」
  • 3)、「客户端发送数据」
  • 4)、「服务端发送数据」

SSL(Secure Sockets Layer) 安全套接层握手过程

1)、生成随机数 1、2、3 的过程

究极深入Android网络优化——网络筑基(一)_第19张图片

2)、双端根据随机数 1、2、3 与相同的算法生成对称秘钥进行加密通信

究极深入Android网络优化——网络筑基(一)_第20张图片

「HTTPS 综合地运用了对称加密与非对称加密,在进行随机数校验的阶段是使用了非对称加密来进行通信的,然后等双方都确定了三个随机数之后,就可以使用相同的算法来生成对称秘钥进行加密通信了。HTTPS 的优势在于双端分别生成了秘钥,没有经过传输,减少了秘钥泄漏的可能性」

5、Http2

它的特点如下所示:

  • 1)、「头部压缩」
  • 2)、「多路复用:多路复用允许同时通过单一的HTTP/2连接发送多重请求-响应信息。改善了:在http1.1中,浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制(连接数量),超过限制会被阻塞」
  • 3)、「提升访问速度:相比 http1.1 请求资源所需时间更少,访问速度更快」
  • 4)、「二进制分帧:HTTP2.0 会将所有的传输信息分割为更小的信息或者帧,并对他们进行二进制编码」
  • 5)、「设置请求优先级」
  • 6)、「服务端推送」

6、cookie

「HTTP 是一个无状态协议,因此 Cookie 的最大的作用就是存储 sessionId 用来唯一标识用户。并且,Cookie 本质上就是浏览器里面存储的一个很小的文本文件,内部以键值对的方式来存储」

生存周期

通过 Expires 和 Max-Age 两个属性来设置:

  • Expires:过期时间。
  • Max-Age:表示一段时间间隔,单位是秒,从浏览器收到报文开始计算。

作用域

「我们可以使用 Domain 和 path 属性给 Cookie 绑定域名和路径。如果在发送请求之前,发现域名或者路径和这两个属性不匹配,那么就不会带上 Cookie」。需要注意的是,路径中含有 / 表示域名下的任意路径都允许使用 Cookie。

安全

  • 「带上 Secure:说明只能通过 HTTPS 传输 cookie」
  • 「带上 HttpOnly:说明只能通过 HTTP 协议传输」
  • 「带上 SameSite:预防 CSRF 攻击」

缺点

  • 1)、「安全缺陷:Cookie 很容易被非法用户截获,然后进行一系列的篡改,最后在 Cookie 的有效期内重新发送给服务器」
  • 2)、「容量缺陷:体积上限只有4KB,只能用来存储少量的信息」
  • 3)、「性能缺陷:Cookie 紧跟域名,因此域名下的请求都会携带上完整的 Cookie,这样随着请求数的增多,将会造成巨大的性能浪费,因为请求携带了很多不必要的内容。这里可以通过 Domain 和 Path 指定作用域去解决」

7、HTTP 传输中的常见问题

  • 1)、「跨域问题」
  • 2)、「数据传输」
  • 3)、「队头阻塞」

七、传输层

现在,当设备 A 与 设备 B 相互通信时,我们可以认为它们就是通过一个虚拟的互连网络进行连接的。「在虚拟的互连网络里面已经解决了网络拓扑、数据路由的走向等问题。在传输层重点解决的是两个设备它们直接是如何进行通信的」

1、传输层的主要功能

1)、进程与进程的通信

不同于在单个操作系统内使用的进程间通信(Unix 域套接字、共享内存),网络通信可以跨设备、跨网络进行通信。

2)、端口的概念

  • 「使用端口来标记不同的网络进程」
  • 「端口使用16比特位表示(0~65535)」

常见的协议端口有:

协议 端口
FTP 21
HTTP 80
HTTPS 443
DNS 53
TELNET 23

2、UDP(User Datagram Protocol)用户数据报协议

究极深入Android网络优化——网络筑基(一)_第21张图片

1)、功能

UDP 协议 「不会对数据报进行任何的处理,即不合并,也不拆分数据」

2)、特点

1)、无连接

通信时并不需要提前建立连接。

2)、不保证可靠的数据交付

想发就发,无法保证数据在网络传输过程中是否丢失。

3)、面向报文传输

不对数据做任何处理,而是直接将应用层数据塞进报文里面。

4)、没有拥塞控制

不管网络是否拥塞,它都会把数据给交付出去。

5)、首部开销很小

首部仅仅占用8个字节。

3)、报文结构

究极深入Android网络优化——网络筑基(一)_第22张图片

  • 「UDP 长度最小值为 8, 即仅包括 UDP 首部」
  • 「校验和是用来检测 UDP 的数据报在传输过程中是否出错」

4)、基于 UDP 定制化的 5 个例子

1、来自网页或者 App 的访问

目前,HTTP 往往采取多个数据通道共享一个连接的策略,这样做本来是为了加快传输速度,但是 TCP 严格的顺序策略使得哪怕共享通道,前一个包不来,后一个包即使与前一个包没关系,也要等着,这样就会使时延加大。

而 QUIC(Quick UDP Internet Connection,快速 UDP 互联网连接)协议是 Google 提出的一种基于 UDP 改进的通信协议,其目的是降低网络通信的延迟,提供更好的用户互动体验。

QUIC 会在应用层上自己快速建立连接、减少重传时延、自适应拥塞控制,是应用层定制化的代表。

2、流媒体协议

直播通常都使用 RTMP(Real Time Messaging Protocol,实时消息传输协议),基于 TCP。但对于直播来说实时性比较重要,宁可丢包,也不要卡顿。

对于视频播放来说,有的包可以丢,有的包不能,因为在视频的连续帧李,有的帧重要,有的不重要,如果一定要丢包,隔几个丢一个,其实看视频的人不会感知,但是如果是连续丢帧,就能感知到了,因此在网络不好的情况下,应用一般会选择性地丢帧。

当网络不好的时候,TCP 会主动降低发送速度,这对本来当时就卡的视频来讲无疑是雪上加霜。TCP 应该让应用层马上重传,而不是主动让步。因此,很多直播应用都基于 UDP 实现了自己的视频传输协议。

3、实时游戏

维护 TCP 连接需要在内核维护一些数据结构,但是一台机器能够支撑的 TCP 连接数目是有限的。由于 UDP 是没有连接的,所以在异步 I/O 机制引入之前,UDP 常常是应对海量客户端连接的策略。

在游戏对实时要求比较严格的情况下,可以采用自定义的可靠 UDP 来传输数据包,通过使用自定义重传策略,能够包丢包产生的延迟降到最低,尽量减少网络问题对游戏造成的影响。

4、物联网

Google 旗下的 Nest 建立了 Thread Group,推出了物联网通信协议 Thread,该协议就是基于 UDP 的。

5、移动通信领域

在 4G 网络里,通过移动通信传输数据面对的协议 GTP-U 就是基于 UDP 的。关于移动网络的相关知识我们将在下一篇进行讲解。

3、TCP(Transmission Control Protocol) 传输控制协议初识

1、TCP 报文详解

究极深入Android网络优化——网络筑基(一)_第23张图片

1)、特点

  • 1)、「面向连接:面向连接就像是打电话时需要先拨通电话」
  • 2)、「点对点通信」
  • 3)、「可靠的传输服务」
  • 4)、「全双工通信:两个设备在连接时,它们都可以同时地发送数据与接收数据」
  • 5)、「面向字节流的协议:TCP 处理的是一个一个的字节,所以TCP 很可能会取出数据中的某一段进行传输,而剩下的数据会把它放到第二个及之后的 TCP 报文中进行传输。因此 TCP 协议可能会对用户的数据进行合并或分拆」

TCP 的缺点在于 「传输效率慢,因为它需要建立连接、发送确认包等等」

2)、报文首部字段

究极深入Android网络优化——网络筑基(一)_第24张图片

序号
  • 表示范围为 0 ~ 2^32 - 1
  • 「因为 TCP 是面向字节流的,所以每一个字节都有一个与之对应的序号」
  • 「TCP 数据报的序号就是数据报中第一个字节的序号」
确认号
  • 表示范围为 0 ~ 2^32 - 1
  • 「表示期望收到数据的首字节序号,如果确认号为 S,则表示 S - 1 序号的数据都已经收到了」
数据偏移
  • 「占4位:0 ~ 15,单位为:32位字。=> 首部范围为20~60字节」
  • 「TCP 数据偏移首部的距离,因为 TCP 选项的大小是不确定的,所以需要此数据项」
TCP 标记

「占6位」,每位都有不同的含义。

标记 含义
URG(Urgent) 紧急位,URG = 1,表示紧急数据。
ACK(Acknowledgement 确认位,ACK = 1,确认号才生效。
PSH(Push) 推送位,PSH = 1,表示需要尽快地把数据交付给应用层。
RST(Reset) 重置位,RST = 1,重新建立连接。
SYN(Synchronization) 同步位,SYN = 1表示连接请求报文。
FIN(Finish) 终止位,FIN = 1表示释放连接。
窗口
  • 占16位:0 ~ 2 ^ 16 - 1
  • 「窗口指明允许对方发送的数据量。例如:确认号为201,窗口为300,那么可以接收序号的范围为 201 ~ 500」
校验和

与 UDP 类似,用来检测 TCP 的数据在传输过程中是否出错。

紧急指针
  • 「紧急数据(URG = 1)」
  • 「指定紧急数据在报文中的位置」
TCP 选项
  • 「最多40字节」
  • 「支持未来的扩展」

4、可靠传输的基本原理

1)、停止等待协议

当发送方发送一个消息时,接收方接收到了并将确认信息发给发送方,这个过程中 「发送方需要停止等待接收方的确认信息」

超时重传

当消息发送出去后,发送方并没有在超时时间内接收到接收方的确认消息或者超时了之后消息才收到,此时会向发送方重新发送该消息。超时重传**「通常都会处理三种异常情况」**,如下所示:

  • 1)、「发送的消息在路上丢失了」
  • 2)、「确认的消息在路上丢失了」
  • 3)、「确认的消息超时了才到」

超时定时器(超时重传定时器)

  • 1)、「每发送一个消息,都需要设置一个超时定时器」
  • 2)、「主要应用在 TCP 的可靠传输协议里面,它是为了控制可能发生丢失的报文而设计的定时器,当 TCP 协议发送端发送一个报文时,就会为该报文设置一个超时定时器」
  • 3)、「如果超时定时器在结束之前收到了来自接收端对该报文段的确认,则撤销这个定时器」
  • 4)、「如果在超时定时器结束之前仍然没有收到来自接收端对该报文段的确认(超时),则认为这个报文可能已经丢弃,发送端会重新发送该报文,并设置一个超时定时器」
  • 5)、「需要注意的是,发送端在超时定时器撤销之前,必须继续缓存已发送未确认的报文,直到发送端收到了来自接收端的确认」

特点

  • 1、「停止等待协议是最简单的可靠传输协议」
  • 2、「对信道的利用效率不高」

既然单个发送和确认效率低,那么我们可以批量发送和确认吗?

2)、连续 ARQ(Automatic Repeat Request) 自动重传请求协议

ARQ 是对停止等待协议的改进,可以 「大幅提升信道利用率」 的一个协议。

滑动窗口

  • 1)、「窗口中的数据都可以发送」
  • 2)、「通过移动窗口的方式来标识没有接收到确认的消息」
  • 3)、「采用了累积确认的方式,并不需要对每一个消息都进行确认」

累积确认

只要我收到第5个消息的确认了,就表示第 1 ~ 5 个消息接收方都收到了。

5、TCP 协议的可靠传输

TCP 的可靠传输基于连续 ARQ 协议。

  • 1)、「滑动窗口」
  • 2)、「累积确认」
  • 3)、「选择重传」

选择重传

  • 1)、「选择重传需要制定需要重传的字节」
  • 2)、「每一个字节都有唯一的32位序号(4字节)」
  • 3)、「要重传的数据是存储在 TCP 选项 中,其中最多只能存储10个序号,即 5 个范围段的信息」
  • 4)、「选择重传的是一个信息边界,即一段字节流,例如:传送 1000 ~ 1200, 2000 ~ 3000 这个范围内的信息」

6、TCP 协议的流量控制

流量控制指的是 「让发送方发送速率不要太快。TCP 使用了滑动窗口来实现流量控制」

1)、滑动窗口

  • rwnd = 300 ,表示窗口大小为300。
  • 占16位:0 ~ 2 ^ 16 - 1。
  • 窗口指明允许对方发送的数据量。例如:确认号为201,窗口为300,那么可以接收序号的范围为 201 ~ 500。
  • 「接收方可以调整滑动窗口的大小来控制发送方发送数据的效率」
  • 「当接收方将 rwnd 从0调整为1000并将这个信息发送给发送方时,消息丢失了,这就会导致发送方和接收方都会等待,形成一个死锁局面」

如何解决这种死锁局面呢?

2)、坚持定时器

坚持定时器是使用滑动窗口进行流量控制的时候设置的。

  • 1)、「当接收到窗口为0的消息,则启动坚持定时器」
  • 2)、「坚持定时器每隔一段时间发送一个窗口探测报文」

7、TCP 协议的拥塞控制

问题

  • 一条数据链路经过非常多的设备。
  • 数据链路中各个部分都有可能成为网络传输的瓶颈。

流量控制与拥塞控制的区别

「不同于流量控制考虑的是点对点的通信量的控制,拥塞控制考虑的是整个网络,是一个全局性的考虑」

如何判断是否发生了拥塞?

「简单地认为报文超时就发生了拥塞」

TCP 的拥塞控制

1)、慢启动算法
  • 「由小到大逐渐增加发送数据量(呈指数增长,例如:1、2、4、8、16)」
  • 「每收到一个报文确认,就加一」
  • 「超过慢启动阈值(ssthresh) 则不再增长」
2)、拥塞避免算法
  • 「维护一个拥塞窗口的变量」
  • 「只要网络不拥塞,就试探着将拥塞窗口调大」

「TCP 的拥塞控制在前期使用了 慢启动 算法对窗口大小进行指数增长,直到超过慢启动阈值(ssthresh)则不再增长,后续则启动拥塞避免算法对窗口进行线性增长」

8、TCP 链接的建立 - 三次握手

究极深入Android网络优化——网络筑基(一)_第25张图片

为什么发送方要发出第三个确认报文呢?

  • 1)、「已经失效的连接请求报文传送到对方,引起错误:假设两次握手就可以,失效的链接请求报文就会被接收并建立了重复的连接。当使用三次握手时,比较慢到达接收方的报文也会发送一个确认给发送方,但是发送方已经进行了第三次握手了,因此发送方会忽略掉第二次的确认,不会进行任何的操作」
  • 2)、「因为信道不可靠,而 TCP 想在不可靠信道上建立可靠地传输,那么三次通信是理论上的最小值。(而 UDP 则不需建立可靠传输,因此 UDP 不需要三次握手)」
  • 3)、「因为双方都需要确认对方收到了自己发送的序列号,确认过程最少要进行三次通信」

9、TCP 链接的释放 - 四次挥手

究极深入Android网络优化——网络筑基(一)_第26张图片

1)、等待计时器

  • 会等待 2MSL 时间 => 4分钟。
  • 时间等待定时器是由是在四次挥手时由主动关闭 TCP 连接的一方设置的,它主要是为了 「保证主动关闭方在对最后一个 FIN 报文(第三次挥手)发送确认的报文可以到达接收方」
  • MSL(Max Segment Lifetime): 最长报文段寿命。MSL 建议设置为2分钟。

2)、为什么需要等待 2MSL?

  • 1)、「因为最后一个报文没有确认,我们需要确保发送方的 ACK 可以达到接收方,如果 2MSL 时间内没有收到,则接收方会重发」
  • 2)、「2MSL 时间可以保证当发送方没有收到确认时,接收方可以再次发送 FIN 报文,并且接收方可以再次收到并重新发送确认,所以 2MSL 的时间可以保证连接正常结束」
  • 3)、「确保当前连接的所有报文都已经过期了」

10、TCP 与UDP 的区别

  • 1)、「UDP 通常用于多媒体信息分发,即视频、语音、实时信息 等等。而 TCP 通常用于可靠信息的传输,应用场景包括金融交易、可靠通信、MQ 等等」
  • 2)、「TCP 面向连接,UDP 是无连接的」
  • 3)、「TCP 提供可靠的服务,也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付」
  • 4)、「TCP 的逻辑通信信道是全双工的可靠信道;UDP 则是不可靠信道」
  • 5)、「每一条 TCP 连接只能是点到点的;UDP 支持一对一,一对多,多对一和多对多的交互通信」
  • 6)、「TCP 面向字节流(可能出现黏包问题),实际上是 TCP 把数据看成一连串无结构的字节流;UDP 是面向报文的(不会出现黏包问题)」
  • 7)、「UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 IP 电话,实时视频会议等)」
  • 8)、「TCP 首部开销20字节;UDP 的首部开销小,只有 8 个字节」

11、套接字(Socket)

我们可以使用端口(Port)来标记不同的网络进程,而端口使用了16比特位表示(0~65535)。

1)、Socket 概念

  • 套接字是一个抽象的概念,表示 TCP 连接的一端。
  • 通过套接字可以进行数据的发送或接收。
  • TCP = { Socket1:Socket2} = {{IP:Port}{IP:Port}},可以看到,TCP 由两个套接字组成。

2)、Socket 编程

服务端编程

  • 1)、「创建 Socket」
  • 2)、「绑定 Socket」
  • 3)、「监听 Socket」
  • 4)、「接收 & 处理信息」

其代码如下所示:

import socket


def server():
    # 1、创建 Socket
    s = socket.socket()
    host = "127.0.0.1"
    port = 5678

    # 2、绑定 Socket
    s.bind(host, port)

    # 3、监听
    s.listen()

    # 4、发送数据
    while True:
        c, addr = s.accept()
        print("connect addr", addr)
        c.send(b'Socket Study.')
        c.close()

客户端编程

  • 1)、「创建 Socket」
  • 2)、「连接 Socket」
  • 3)、「发送消息」

其代码如下所示:

import socket


def client(i):
    # 1、创建 Socket
    s = socket.socket()

    # 2、连接 Socket
    s.connect(('127.0.0.1', 5678))

    # 3、接收消息
    print("Received message:%s, client Id:%d" % (s.recv(1024), i))
    s.close()


if __name__ == '__main__':
    for i in range(10):
        client(i)

单机通信更推荐使用域 Socket,相比网络通信数据需要在整个协议栈走一轮,域 Socket 它的处理流程更加简单,系统消耗更加小。此外,如果对 Socket IO 实现机制有兴趣的同学可以 点击此处.

12、TCP 协议细节之 TCP 协议的四个定时器

  • 1)、「超时定时器」
  • 2)、「坚持定时器」
  • 3)、「时间等待定时器」
  • 4)、「保活定时器」:服务端一般都会设置一个保活定时器,它是为了保活 TCP 连接而设计的,可以防止 TCP 连接的两端出现长时间的空闲,当一方出现变化或故障时,另一方没有察觉的情况。 当服务端每次收到对方的数据则重置这个定时器,如果定时器超时,则会发送弹出报文段,以此探测客户端是否在线,如果没有收到响应的话,那么则认为客户端已经断开连接了,因此服务端也会终止这个链接。现如今,很多的分布式系统都会使用保活定时器来检测其它节点是否在线还是已经故障,或者其它节点也会每隔一段时间向主节点上报心跳信息以证明在线。

13、TCP 在三次握手的时候,IP 层和 MAC(Medium Access Control) 层在做什么呢?

其实 TCP 每发送一个消息,都会带着 IP 层和 MAC 层。因为 TCP 每发送一个消息,IP 层和 MAC 层的所有机制都要运行一篇。

需要注意的是,「只要是在网络上跑的包,都是完整的。可以有下层没上层,绝对不可能有上层没下层。所以,对 TCP 来说,无论是三次握手还是重试,只要想包网络包发送出去,就要有 IP 层和 MAC 层,不然是发不出去的」
原文:jsonchao

你可能感兴趣的:(究极深入Android网络优化——网络筑基(一))