本文由百度技术团队“蔡锐”原创发表于“百度 App 技术”公众号,原题为《百度 App 网络深度优化系列《三》弱网优化》,感谢原作者的无私分享。
一、前言
网络优化解决的核心问题有三个,第一是安全问题,我们在《百度 APP 移动端网络深度优化实践分享(一):DNS 优化篇》进行了详细的讲解。第二是速度问题,我们在《百度 APP 移动端网络深度优化实践分享(二):网络连接优化篇》也做了详细的介绍。第三是弱网问题,它是网络优化中最为复杂且需要反复验证和分析的问题,我们的《百度 APP 移动端网络深度优化实践分享(三):移动端弱网优化篇(本文 *)》就是要深入探讨这个问题。
本系列文章目录如下:
《百度 APP 移动端网络深度优化实践分享(一):DNS 优化篇》
《百度 APP 移动端网络深度优化实践分享(二):网络连接优化篇》
《百度 APP 移动端网络深度优化实践分享(三):移动端弱网优化篇》(* 本文)
(本文同步发布于:http://www.52im.net/thread-26…)
二、相关文章
《TCP/IP 详解 – 第 11 章·UDP:用户数据报协议》
《Android 程序员必知必会的网络通信传输层协议——UDP 和 TCP》
《网络编程懒人入门(四):快速理解 TCP 和 UDP 的差异》
《网络编程懒人入门(五):快速理解为什么说 UDP 有时比 TCP 更有优势》
《技术扫盲:新一代基于 UDP 的低延时网络传输层协议——QUIC 详解》
《让互联网更快:新一代 QUIC 协议在腾讯的技术实践分享》
《现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障》
《移动端 IM 开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》
《移动端 IM 开发者必读(二):史上最全移动弱网络优化方法总结》
三、技术背景
弱网优化需要解决的核心问题有两点:
1)移动网络环境如此复杂,我们如何确定当下就是弱网环境;
2)确定为弱网环境下,我们如何提升弱网下的成功率,降低弱网下的时延,进而提升用户的网络体验。
百度 App 承载着亿级流量,弱网比例 0.95%,可谓不小,这个比例是如何得来的呢?还是要从什么是判断弱网指标说起。
四、判断弱网的指标
首先我们来探讨下都有哪些指标会影响到网络的质量,包括 httprtt,tcprtt,throughput,signal strength,bandwidth-delay product。
1)httprtt:
httprtt(http Round-Trip Time)又名 TTFB(Time to first byte),指从客户端请求的第一个字节开始发送到接收到 http header 的第一个字节的时间差。httprtt 的时间如果过长,一方面是客户端本身接入网络质量的问题,另一方面是服务的延时比较大。
2)tcprtt:
tcprtt(tcp Round-Trip Time)指客户端 tcp 信道第一个字节发送到接收第一个字节的时间差。因为 HTTP 协议底层是基于 TCP 的,所以在复用同一条 tcp 连接的前提下,httprtt 的时间是包含 tcprtt 的时间的。大部分情况下 httprtt 已经可以说明问题的原因。
3)throughput:
throughput,中文名字吞吐量,它是用来衡量单位时间内成功传送数据的数量,是可以比较客观的衡量网络质量的指标。吞吐量 =(获 bits 结束大小 – 获 bits 开始大小)/(获 bits 结束时间 – 获 bits 开始时间),这里有个细节需要注意,posix socket 的 read 函数返回值是 bytes,所以要乘以 8 得到 bits。通常在 httprtt 比较小的情况下,网络依然很慢,这个时候就可以使用吞吐量来确定网络的质量。
4)signal strength:
signal strength,这里指的是无线信号强度,在 Android 上可以通过 PhoneStateListener 的 onSignalStrengthsChanged 方法获取到信号强弱,但要注意只能在 Android M 以上的版本才生效。iOS 上暂时没有靠谱的实现。
5)bandwidth-delay product:
bandwidth-delay product,中文名带宽时延乘积,指的是一个数据链路的能力(throughput)与来回通信延迟(rtt)的乘积。带宽时延乘积的结果是比特不是位,这个比特值反应出当前网络管道的最大容量。TCP 中有一个窗口大小的概念,会限制发送和接收数据的大小,所以 TCP 窗口大小的调节是直接受带宽时延乘积的影响,根据带宽时延乘积的值去设置套接字的 setsockopt 方法,设置的 option 是 SO_RCVBUF(接收缓冲区大小)和 SO_SNDBUF(发送缓冲区大小)。
通过上面的内容,我们对影响网络质量的指标有了一定了解,对于不同的产品,影响网络质量的指标可以理解成一样的,但对于每个指标的阈值肯定是不一样的,因为这包含着业务场景,比如抖音是视频类网络传输,微信是长连接数据传输,百度是文本图片类数据传输。还包括服务端配备,不同产品线的服务集群能力肯定不一样,比如返回客户端的服务端耗时肯定不一样。所以针对不同的产品弱网指标是基本一致的,但是指标的取值肯定是不一样的。
五、如何建立弱网标准
建立弱网标准是一个循序渐进的过程,在一穷二白的时候我们应该如何建立这个标准呢?答案分为三个阶段。
▲ 建立弱网标准的步骤
1)第一阶段,线下进行测试:获取一些符合我们预期的阈值,这个时候我们需要借助一些网络测试工具,比如苹果的 Network Link Conditioner,Facebook 的 ATC(Augmented Traffic Control),来获取到线下不同网络情况的阈值,一般我们会测试 App 冷启动的场景,网络切换的场景,DNS 故障场景,弱网场景(一般都是配置上下行的带宽,丢包率,延迟,DNS 延迟参数,或者更为简单的是使用工具默认的一些弱网配置)。
2)第二阶段,线上进行验证:通过线下充分测试获取到的阈值,在线上可以获取到弱网的比例,在这里百度 App 是针对特定场景的,比如 Feed 刷新,搜索落地页打开等,就算是在移动时代被大家公认的网络体验好的微信,也只是在信令传输(收发消息)上做到极致优化,所以针对场景搜集弱网数据很重要。
3)第三阶段,线上的反复试验:想做到理想的弱网效果,少不了线上反复的阈值调整,通过调整阈值比较针对场景的网络请求的成功率、耗时、连接复用率等指标,使我们获得趋向于针对场景的合理阈值。
聊了这么多,那么弱网的探测如何实现呢?
六、网络探测的整体架构和实现
网络探测是弱网检测的基础,是否能即时,正确的检测出网络质量,是我们首先要解决的问题。我们把网络探测划分为两部分,主动网络探测和被动网络采集。
6.1 主动网络探测
所谓主动探测,就是在触发了某些条件后,主动的进行网络探测,并按照一定的条件检查出是否是弱网状态。百度 App 自研了主动探测组件,如下图所示。
▲ 主动网络探测
(6.1.1)策略层:
探测策略层通过多种策略的组合,使主动探测的即时性和准确性得以大大提高,我们结合上面的策略层图来解释下检测维度的意义。
我们分别在网络请求成功和失败的时候触发了弱网检测的逻辑。
主要分为如下三种逻辑:
1)成功时,如何判断进入弱网状态?检查 weakhttprtt 的阈值,这个值取决于业务的设置(一般这个值会针对特殊场景的请求取 95 分位或者更大分位的值),大于这个值就会进入弱网检测,为了防止频繁触发探测加了时间间隔维度,目前定义的是 10 分钟。从线下模拟测试来看,只要大于这个阈值,检测结果必然是弱网状态。
2)成功时,如何判断退出弱网状态?检查 goodhttprtt 的阈值,这个值取决于业务的设置(一般这个值会取整体网络的 95 分位或者更大分位的值),小于这个值证明要切换回正常网络状态,为了防止频繁触发探测加了时间间隔维度,目前定义的是 30 秒。从线下模拟测试来看,只要小于这个阈值,检测结果必然是正常状态。如果大于或者等于这个阈值,也不能证明一定不是正常网络,所以也需要发起网络探测,但是由于这是在成功回调里,频次会很高,所以我们加上时间间隔的限制 30 秒,还加入了次数的限制,连续成功次数 % 次数阈值(4 次)等于 0。但这看起来还是频次有点高,所以我们引入了阶梯递增机制,随着次数的增长,成 60 秒几何倍数增长。
3)失败时,如何判断进入弱网状态?首先会判断连续失败次数,连续失败次数 / 次数阈值(2 次)等于 1 并且连续失败次数 % 次数阈值(2 次)等于 0,相比成功,失败的次数检查较为苛刻,主要还是考虑多次触发网络检测损耗性能。
进入弱网状态后,就会触发基础能力层的 ping 和 dns query 的探测。
(6.1.2)基础能力层:
探测基础能力层,主要提供弱网检测的手段,一是 dns query,一是 ping,百度 App 使用 C ++ 实现了这两个能力。
为什么要选用这两种手段呢?我们在系列二中介绍过,一个网络请求,分为 DNS->TLS->TCP-> 数据传输 四个阶段。想判定网络连通性主要在 DNS 和 TCP 阶段,所以 dns query 和 ping 就是用来检测这两个阶段的连通性手段。dns query 向百度核心域名 mbd.baidu.com 发起 dns 查询,查询的 DNS 服务器为系统配置的 DNS 服务器(iOS 通过 res_ninit 函数构建一个__res_state 的结构体,Android 通过 systemproperty 获取 net.dns1 和 net.dns2 的值,便可获取系统配置的 DNS 服务器),DNS 查询的超时时间为 3s。ping 的目标地址为百度核心域名 mbd.baidu.com,ping 的次数为两次,每次超时时间是默认的 1s。
判断出弱网状态后,会将结果提供给接口层。
(6.1.3)接口层:
接口层主要提供主动探测出来的网络状态,目前包括 GOOD,BAD,UNKNOWN,OFFLINE。
1)GOOD:dns 查询成功并且 ping 也成功,即标记为 GOOD 状态;
2)BAD:ping 失败一次标记为 BAD 状态;
3)UNKNOWN:初始状态或者识别不出来状态为 UNKNOWN 状态;
4)OFFLINE:dns server 错误(没有获取到要发送的 DNS server 地址),网关错误(读取 /proc/net/route 文件内容失败),发送 dns 错误(发送 dns 数据出错),ping 读写错误(ping 的过程中读写错误),接收 dns 错误(接收 dns 数据出错),ping 地址错误(ping 地址是空),dns 未知域名错误(dns 没有查询到域名错误),初始化 icmp 错误(初始化 icmp 失败),dns udp 错误(创建 UDP socket 失败),即标记为 OFFLINE 状态。
6.2 被动网络采集
所谓被动采集,就是每一次网络请求的所有细节都进行记录,并按照一定的条件将原始信息进行上报,上层再根据条件判断是否是弱网状态。百度 App 基于 cronet 的 NQE(Network Quality Estimator)进行了二次订制开发。
首先我们讲解下需要采集的数据,包括 tcprtt、httprtt、throughput 三个维度,如下图所示。
▲ 被动采集数据
1)tcprtt,基于 posix 和 windows 的 socket 编程接口来获取 tcprtt。获取时机在连接完成,读完成和写完成;
2)httprtt,基于 HTTP 协议栈实现,通过计算接收 response 数据开始和开始发送的时间差,来获取 httprtt。获取时机在读首包完成时;
3)throughput,通过上面的计算公式需要获取 bytes 和时间,基于 posix 和 windows 的 socket 编程接口来获取 bytes。获取时机在读完成时记录接收的 bytes,在写完成时记录发送的 bytes。时间的获取在吞吐量管理模块里完成,下面会讲到。获取时机在请求完成和请求销毁时。
如下为被动网络采集的整体架构图。
▲ 被动网络采集
(6.2.1)能力层:
能力层内容上面我们已经讲过,主要采集 tcprtt、httprtt、throughput 三个维度的数据。
(6.2.2)策略层:
被动采集策略层通过多种策略的组合,降低各种采集数据的上报时机,降低性能的影响。
1)套接字管理模块,首先负责获取 tcprtt 的值,如何获取 tcprtt 呢?通过 getsockopt 函数获取 tcp_info 结构体里的 tcpi_rtt 值。其次由于 tcprtt 的上报频次比较频繁,所以做了 1 秒的时间间隔上报限制。
2)吞吐量管理模块,负责吞吐量的计算,上面介绍了计算公式,从网络活动监控器模块获取 bytes,但吞吐量的计算单位是 bits(位),所以将 bytes 乘以 8。只有 GET 请求会被列入统计计算,并且至少要累计 5 个请求后才能开始统计计算。排除精准度的干扰,比如 localhost,私有子网上的主机,特定用途子网主机,可参考 RFC1918。
3)网络质量管理模块,从套接字管理模块获取 tcprtt,从吞吐量管理模块获取吞吐量,并且在 HTTP 协议栈读首包完成时获取 httprtt。获取到这三个值后,需要经过一些策略限制上报的频次,10 秒间隔的限制;网络类型不能是 UNKNOWN(下文会详细讲解);网络不能频繁切换;rtt 和吞吐量总大小各 300 个。
(6.2.3)接口层:
接口层主要提供被动采集出来的网络状态,目前包括 GOOD,BAD,UNKNOWN,OFFLINE。
1)GOOD:3G 和广义的 4G,任一条件满足标记为 GOOD 状态。通过阈值标记 3G 和广义的 4G,httprtt 大于等于 273ms,tcprtt 大于等于 204ms,即标记为 3G 状态。小于这两个值被标记为广义的 4G,所谓广义的 4G 包含 4G、WiFi、以及质量较好的各种接入网络。
2)BAD:慢 2G,2G 和 httprtt 大于 1.31 秒,任一条件满足标记为 BAD 状态。通过阈值标记慢 2G 和 2G,httprtt 大于等于 2.01 秒,tcprtt 大于等于 1.87 秒,标记为慢 2G。httprtt 大于等于 1.42 秒,tcprtt 大于等于 1.28 秒,标记为 2G。httprtt 大于 1.31 秒,为百度 App 的 Feed 刷新业务阈值。
注:上面涉及的时间值为 nqe 内部的机制,具有普适性。
3)UNKNOWN:非法的 httprtt,tcprtt,吞吐量,任一条件满足标记为 UNKNOWN 状态。何为非法?值为 - 1 为非法,那什么条件被标记为 - 1 呢?首先初始化时会被标记为 -1,其次在从来没有获取到过 httprtt,tcprtt,throughput 的值时,会使用本地默认的值做为判断标准,这是一种容错处理。
4)OFFLINE:依赖平台能力进行判断,Android 平台依赖 ConnectivityManager 获取 NetworkInfo,通过 NetworkInfo 的 isConnected 获取是否连接,如果未连接则判断为 OFFLINE 状态,如果 NetworkInfo 为空则判断为 OFFLINE 状态。
七、弱网状态下百度 App 如何改善用户体验
▲ 百度 App 在弱网下的手段
7.1 QUIC 在百度 App 弱网下的最佳实践
QUIC(Quick UDP Internet Connections)是新一代的互联网传输协议,最早源于 Google,它的详尽内容可参考资料:https://www.wolfcstech.com/20…(也可以读一读本站的文章:《技术扫盲:新一代基于 UDP 的低延时网络传输层协议——QUIC 详解》),本章我们不做 QUIC 的科普介绍。
百度 App 的普通网络请求在弱网状态下会切换到 QUIC,本章重点讲解下百度 App 针对弱网下开启 QUIC 后遇到的问题,一是开启 QUIC 一旦遇到问题是否可以回滚?二是在弱网下如何能让流量尽可能的走 QUIC?针对这两个问题,我们的解决方案是 QUIC 升降级原理和 QUIC 预连接。
(7.1.1)QUIC 升降级原理:
如上图 QUIC 部分所示,QUIC 的升降级依赖于 HTTP Alternative Services,HTTP Alternative Services 是与 HTTP 有关的一个协议,它不是为 QUIC 专门设计的,在 HTTP 协议上主要负责新服务的替换,对于 HTTP1.1 协议,它是通过 HTTP 响应头传输回来的,所以只能在第二次请求时生效,如下面格式。
Alt-Svc: quic=”alt.example.com:443″, quic=”:443″; ma=2592000
如上信息表明切换到 quic 协议,指定了域名服务和端口,并且指定了生效时间,以秒为单位。
Alt-Svc: clear
如上信息表明将 alter 配置清空
在网络库内部有一个 alter 连接和原连接的竞争机制,如果 alter 信息已经存在,优先发送 alter 连接,而原连接会延迟发送,延迟时间默认 300ms,谁先成功就使用哪个连接,如果 alter 连接在 QUIC 握手时失败,会记录这个 alter 信息的失败次数,并根据失败的次数,计算出一个过期时间,这个过期时间会随失败次数指数增加,最长为 2 天。当过期时间到期后,会清除这个 alter 信息,当这个 alter 连接在 QUIC 握手成功后,会清除这个 alter 信息。
(7.1.2)QUIC 预连接:
所谓 QUIC 的预连接,就是在进入弱网状态前提前建立 QUIC 连接。大家都知道 QUIC 引以为傲的 0RTT,但第一次建立连接的时候是需要 1RTT 的,客户端首先会向服务器发送一个 client hello 消息,服务器会回复一个 server reject 消息,这个消息中包括了 server config,有了 server config 后客户端就可以直接计算出密钥,完成 0RTT,详尽内容可参考 [url= https://www.wolfcstech.com/2017/ … %E5%8D%8F%E8%AE%AE/] 资料【4】[/url]。
通过上面的原理,客户端拉取 server config 的成功概率会直接影响 QUIC 在弱网下的流量,所以我们在 App 启动的过程中会做一次 QUIC 预连接,将 server config 拉取下来,这样等进入弱网后 alter 连接会大概率的竞争过原连接,进而走 QUIC 协议。
7.2 复合连接在百度 App 弱网下的最佳实践
复合连接的具体原理可以查看《百度 APP 移动端网络深度优化实践分享(二):网络连接优化篇》里的具体介绍,百度 App 目前在弱网下只是针对图片网络请求开启了复合连接,因为图片请求不管是 HTTPDNS 结果还是 localDNS 的结果都是多个 IP,这是满足复合连接的前提。在弱网下多 IP 的尝试会比单 IP 的结果好些,另外弱网的比例相对较小,复合连接对于服务器的负载也会小些。
八、百度 App 网络整体架构
▲ 百度 App 网络整体架构
百度 App 网络整体架构,以网络门面为中间层,隔离上层的最佳实践和底层的基础网络库。
1)最佳实践:
客户端网络库的一部分工作量是在如何让最佳实践做的更好,在音视频上,不管是 iOS 的 AVPlayer,还是双端的 ijkPlayer,都是使用 HTTPDNS 组件接管 DNS 模块,没有全部接管网络模块。ReactNative 的网络模块 RCTNetworking,图片库 Android 的 Fresco 和 iOS 的 SDWebImage,WebView 组件 Android 的 Chromium 和 iOS 的 WKWebView,以及百度 App 的自有业务,都是通过网络门面的接口层直接接管。而对于第三方业务考虑到与宿主耦合的关系,直接使用 Android 的 HttpURLConnection 和 iOS 的 URLSession 系统标准的接口。
2)网络门面:
网络门面主要包括:
a. 拦截器模块(提供给业务订制网络门面的机制);
b. 并发队列模块(提供高中低以及非常高的网络请求优先级);
c. 网络探测组件(弱网主动探测能力)、网络诊断模块(包括 https,ping,dns 的校验);
d. HTTPDNS 组件(《百度 APP 移动端网络深度优化实践分享(一):DNS 优化篇》里详细讲解);
e. 网络监控模块(客户端的打点机制,服务端的例行和突发监控);
f. HttpURLConnection 封装层;
g. URLSession 封装层。
3)基础网络库:
基础网络库包含两部分:
一部分是基于 cronet 二次订制的统一网络库;
一部分是 WebSocket 基础库(Android 的 JavaWebSocket,iOS 的 SocketRocket)。
统一网络库内部包含连接优化的内容(在《百度 APP 移动端网络深度优化实践分享(二):网络连接优化篇》里详细讲解),弱网优化的内容(上面提到的被动采集)。通过 AOP 的方式将底层协议栈注入进 HttpURLConnection(利用 URLStreamHandlerFactory)和 URLSession(利用 URLSessionConfiguration 的 protocolClasses 属性),两者都是系统提供的 URL Loading 机制。
九、实际收益
弱网优化的收益我们主要从上面讲到的进入弱网状态后的手段来看,包括开启 QUIC,QUIC 预连接,开启复合连接。
1)弱网下开启 QUIC 后,网络连接成功率提升 0.01%,平均耗时降低 23.5%;
2)弱网下开启 QUIC 预连接后,QUIC 协议的 pv 从 37 万涨到 90 万;
3)弱网下开启复合连接后,bad 状态下耗时降低 2.5%,offline 状态下耗时降低 7.7%。
十、本文结语
系列一到系列三的内容到今天全部完成,希望能对大家的工作和学习有所帮助,感谢大家的持续关注和鼓励。生命不息,优化不止,做技术我们是认真的。
十一、参考资料
[1] https://chromium.googlesource…
[2] https://chromium.googlesource…
[3] https://www.wolfcstech.com/20…
[4] https://www.wolfcstech.com/20…
[5] https://tools.ietf.org/html/r…
[6] https://github.com/Tencent/mars
附录:更多网络通信方面的精华文章
《TCP/IP 详解 – 第 11 章·UDP:用户数据报协议》
《TCP/IP 详解 – 第 17 章·TCP:传输控制协议》
《TCP/IP 详解 – 第 18 章·TCP 连接的建立与终止》
《TCP/IP 详解 – 第 21 章·TCP 的超时与重传》
《技术往事:改变世界的 TCP/IP 协议(珍贵多图、手机慎点)》
《通俗易懂 - 深入理解 TCP 协议(上):理论基础》
《通俗易懂 - 深入理解 TCP 协议(下):RTT、滑动窗口、拥塞处理》
《理论经典:TCP 协议的 3 次握手与 4 次挥手过程详解》
《理论联系实际:Wireshark 抓包分析 TCP 3 次握手、4 次挥手过程》
《计算机网络通讯协议关系图(中文珍藏版)》
《UDP 中一个包的大小最大能多大?》
《P2P 技术详解(一):NAT 详解——详细原理、P2P 简介》
《P2P 技术详解 (二):P2P 中的 NAT 穿越(打洞) 方案详解》
《P2P 技术详解(三):P2P 技术之 STUN、TURN、ICE 详解》
《通俗易懂:快速理解 P2P 技术中的 NAT 穿透原理》
《高性能网络编程(一):单台服务器并发 TCP 连接数到底可以有多少》
《高性能网络编程(二):上一个 10 年,著名的 C10K 并发连接问题》
《高性能网络编程(三):下一个 10 年,是时候考虑 C10M 并发问题了》
《高性能网络编程(四):从 C10K 到 C10M 高性能网络应用的理论探索》
《高性能网络编程(五):一文读懂高性能网络编程中的 I / O 模型》
《高性能网络编程(六):一文读懂高性能网络编程中的线程模型》
《不为人知的网络编程(一):浅析 TCP 协议中的疑难杂症(上篇)》
《不为人知的网络编程(二):浅析 TCP 协议中的疑难杂症(下篇)》
《不为人知的网络编程(三):关闭 TCP 连接时为什么会 TIME_WAIT、CLOSE_WAIT》
《不为人知的网络编程(四):深入研究分析 TCP 的异常关闭》
《不为人知的网络编程(五):UDP 的连接性和负载均衡》
《不为人知的网络编程(六):深入地理解 UDP 协议并用好它》
《不为人知的网络编程(七):如何让不可靠的 UDP 变的可靠?》
《不为人知的网络编程(八):从数据传输层深度解密 HTTP》
《网络编程懒人入门(一):快速理解网络通信协议(上篇)》
《网络编程懒人入门(二):快速理解网络通信协议(下篇)》
《网络编程懒人入门(三):快速理解 TCP 协议一篇就够》
《网络编程懒人入门(四):快速理解 TCP 和 UDP 的差异》
《网络编程懒人入门(五):快速理解为什么说 UDP 有时比 TCP 更有优势》
《网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门》
《网络编程懒人入门(七):深入浅出,全面理解 HTTP 协议》
《网络编程懒人入门(八):手把手教你写基于 TCP 的 Socket 长连接》
《网络编程懒人入门(九):通俗讲解,有了 IP 地址,为何还要用 MAC 地址?》
《技术扫盲:新一代基于 UDP 的低延时网络传输层协议——QUIC 详解》
《让互联网更快:新一代 QUIC 协议在腾讯的技术实践分享》
《现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障》
《聊聊 iOS 中网络编程长连接的那些事》
《移动端 IM 开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》
《移动端 IM 开发者必读(二):史上最全移动弱网络优化方法总结》
《IPv6 技术详解:基本概念、应用现状、技术实践(上篇)》
《IPv6 技术详解:基本概念、应用现状、技术实践(下篇)》
《从 HTTP/0.9 到 HTTP/2:一文读懂 HTTP 协议的历史演变和设计思路》
《脑残式网络编程入门(一):跟着动画来学 TCP 三次握手和四次挥手》
《脑残式网络编程入门(二):我们在读写 Socket 时,究竟在读写什么?》
《脑残式网络编程入门(三):HTTP 协议必知必会的一些知识》
《脑残式网络编程入门(四):快速理解 HTTP/ 2 的服务器推送(Server Push)》
《脑残式网络编程入门(五):每天都在用的 Ping 命令,它到底是什么?》
《脑残式网络编程入门(六):什么是公网 IP 和内网 IP?NAT 转换又是什么鬼?》
《以网游服务端的网络接入层设计为例,理解实时通信的技术挑战》
《迈向高阶:优秀 Android 程序员必知必会的网络基础》
《全面了解移动端 DNS 域名劫持等杂症:技术原理、问题根源、解决方案等》
《美图 App 的移动端 DNS 优化实践:HTTPS 请求耗时减小近半》
《Android 程序员必知必会的网络通信传输层协议——UDP 和 TCP》
《IM 开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)》
《IM 开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)》
《IM 开发者的零基础通信技术入门(三):国人通信方式的百年变迁》
《IM 开发者的零基础通信技术入门(四):手机的演进,史上最全移动终端发展史》
《IM 开发者的零基础通信技术入门(五):1G 到 5G,30 年移动通信技术演进史》
《IM 开发者的零基础通信技术入门(六):移动终端的接头人——“基站”技术》
《IM 开发者的零基础通信技术入门(七):移动终端的千里马——“电磁波”》
《IM 开发者的零基础通信技术入门(八):零基础,史上最强“天线”原理扫盲》
《IM 开发者的零基础通信技术入门(九):无线通信网络的中枢——“核心网”》
《IM 开发者的零基础通信技术入门(十):零基础,史上最强 5G 技术扫盲》
《IM 开发者的零基础通信技术入门(十一):为什么 WiFi 信号差?一文即懂!》
《IM 开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!》
《IM 开发者的零基础通信技术入门(十三):为什么手机信号差?一文即懂!》
《IM 开发者的零基础通信技术入门(十四):高铁上无线上网有多难?一文即懂!》
《IM 开发者的零基础通信技术入门(十五):理解定位技术,一篇就够》
《百度 APP 移动端网络深度优化实践分享(一):DNS 优化篇》
《百度 APP 移动端网络深度优化实践分享(二):网络连接优化篇》
《百度 APP 移动端网络深度优化实践分享(三):移动端弱网优化篇》
《技术大牛陈硕的分享:由浅入深,网络编程学习经验干货总结》
更多同类文章 ……
(本文同步发布于:http://www.52im.net/thread-26…)