Android 网络浅析

110 篇文章 12 订阅
5 篇文章 0 订阅

1、网络协议指的是什么

所谓协议,就是一种“规范”、或者说“约定”,在通俗点就是“某种规则”。 平时编程用到语言:java、c++、js等也属于协议。 协议一般包含三个要素:

  • 语法 按照某种规则。如谍战片中的加密电报
  • 语义 根据这种规则,需要表达的意思
  • 顺序 形成某种顺序,包含上下文信息 如 先干什么,然后在干什么等等

那么网络协议,就是应用在网络通信中的一种规范。平时常用到的网络协议有:

分层用到的协议
应用层DHCP(动态主机配置)、DNS(域名系统)、http(普通传输)、https(加密传输)
传输层TCP(面向连接) UDP(无连接协议)
网络层IP
链路层ARP
物理层网络跳线

详细解释: DHCP(动态主机配置): Dynamic Host Configuration Protocol 当设备启动联网后,DHCP负责给设备分配ip地址、默认网关的ip地址。

2、网络分层

网络有五层和七层之分,这里主要讨论五层。如上表所示。 分层可以让复杂问题简单化,每一层专注做自己的事情,层与层之间是有联系的。 发起一个网络请求,想要通过网络到达服务端,那么就需要根据每一层的网络协议去封装具体的请求数据(只有按照这种规则才能成功抵达目标服务器),到达目标服务器后,经过服务器的处理,返回的数据也同样需要经过每一层的网络协议包装,经由网络回到起点。在这样的一个过程中每一层都在什么?

2.1、每一层在都干什么

从网站买一本书为例:

发起侧(从上往下):

分层做了什么
应用层DNS(把服务器的域名解析为对应的ip地址->https/http(加上请求头的信息:json/protobuf格式,加上请求体body:我要买书)
传输层封装当前应用程序在本机上的端口,服务器程序的监听端口
网络层封装当前设备的ip地址,服务器ip地址
链路层封装当前设备ip对应的MAC地址,封装当前网关ip的MAC地址
物理层根据目标ip地址,网卡开始路由分发

接收侧(从下往上):

分层做了什么
应用层 5根据https/http规则进行解析,得到具体请求(我要买书)
传输层 4解析比较当前服务器的端口,与目标服务器程序的监听端口
网络层 3解析比较当前服务器ip地址与 目标服务器ip地址
链路层 2解析当前服务器ip对应的MAC地址,与传递过来的目标MAC地址比较
物理层 1到达目标服务器网关路由(如果这个包我可以拿过来)

注意:

本地网络内部是以MAC地址进行通信的,外地网络是以ip地址来通信的。两者通过网关(就是路由)连接起来。

MAC地址是网卡的唯一标识,类似身份证号码。

ip地址相当于身份证上的门牌地址。 只有知道门牌号+身份证号才能在网络世界中找到你。

MAC: Medium Access Control 媒体访问控制

路由器是一个网络设备,包含多张网卡。当一个网络包进来,路由会根据路由表来进行处理。而路由表一般包含如下规则:

  1. 这个包的目标地址?
  2. 将包该从哪个端口发出?
  3. 下一跳路由网关:下一个路由地址是?

解包的具体流程:

当网络包从网口经过的时候,这里会根据设置的模式来看看这个包是不是需要我来处理下。 拿包进来后,交给layer2层来处理。从数据包中拆下mac头,看看mac头协议我需要做什么。 若mac匹配则交给lyaer3层,否则就转发出去。从包中拆下ip头,根据ip头协议是不是要做什么处理。 若ip匹配则交给layer4层,否则就转发出去。传输层会根据地址来区分,如果是发给tcp的则调用process_tcp来处理。tcp会根据tcp头来判断这是一个发起、还是一个应答、还是一个普通的数据,分不同的逻辑来处理。 处理完成后,在根据应用程序监听的端口来发给具体的应用程序(如web浏览器、手机端的app)。注意,这里不会有再交给http层的概念了。

问题:

1,tcp三次握手的时候,应用层是如何参与?网络层和物理层是如何工作的?

tcp握手时候,应用层是没有参与的。而tcp每发送一个消息,都会带上ip层和mac层。因此,握手过程不除了tcp层,ip层和mac层都在默默辛苦的工作。

每一个在网络上的包,都是完整的。可以没有上层,不能没有下层。

2,二层设备、三层设备指的什么?

所谓的二层、三层设备其实指的是在设备跑的程序不同而已。 因为只要到达了二层,那么这个包就是完整的。如果只拆mac,那么就是二层设备。 如果再拆ip头,那么就是三层设备。

3、TCP/UDP

3.1,TCP与UDP的区别?

TCP是面向连接的,而UDP是面向无连接。

  • TCP在互通之前,需要进行三次握手建立连接。
  • 它是可靠的传输,保证顺序。
  • 具有拥塞机制,当网络不好或者意识到丢包情况,会自动减少数据包的发送。
  • 面向字节流的,以流为单位发送,没有说明什么时候关闭,除非显示关闭(断开连接)。ip包是没有流概念的,流是TCP本身维护的状态
  • 一个有状态的服务,发送了没有?接收了没有?改接收哪个了?等等

UDP继承了ip包特性:

  • 是不可靠的传输。
  • 一经发出,不保证不丢失,不保证顺序。
  • 无状态。无脑发送。
  • 基于数据报,一个一个发送。

mac层叫帧-frame,网络层叫包-package,传输层叫段-segment。统称为包。

3.2,UDP的头是啥样的?

网络层拆解ip头后,里面有一个8位的协议指明了是TCP包还是UDP包,也就是要交给TCP还是UDP来处理。

当传输层拿到UDP头后,里面包含了源应用的端口号和目标应用的端口号。不管是TCP还是UDP都会监听端口号,因此在系统中,端口号是唯一的,一个端口对应一个应用。

UDP的特点就是,沟通传输简单。发数据的时候只管发,不管网络如何,也不管对方是否能接收到。 接收的时候,因为没有连接,只管接收,不管是谁发的我都收。因此,UDP可实现一对多发送。不用一对一建立连接。

在语音和视频直播场景,DHCP配置场景都有UDP的应用。

3.3,TCP

3.3.1 TCP的包头

既然TCP相比UDP,包头复杂很多。包含如下方面:

  1. 源端口地址和目标端口地址
  2. 序号 解决包的乱序问题,不管是发送还是接收都有顺序
  3. 确认序号 解决丢包问题。发出去的包必须受到回包,否则会重新发送。
  4. 状态机 维护连接状态。随着通信双方状态的变化,tcp的连接状态也会随着更新:从建立连接到关闭连接。
  5. 窗口大小 流量大小控制。表明能够处理数据多少的能力。不能太快也不能太慢。
  6. 拥塞机制 网络环境不好时,会自动调整发送速度

注:

TCP无法控制网络环境,只能通过算法在TCP层尽可能的保证可靠。

3.3.2 TCP的三次握手

三次握手的目的是什么?

三次握手做了两件事情:

1,通过发送包、接收包,客户端和服务端各自维护了状态,建立连接。

根据状态机的变化来表示断开开始连接状态。其实本质上网络是不存在状态的,这只是tcp与服务端各自逻辑的实现。

2,确定本次连接数据包的序号 ISN(Initial Sequence Number)

避免网络延迟导致的多次连接后包序混乱。ISN是动态生成。

握手的过程:

简要描述:

  1. 你好,我是A。
  2. 你好A,我是B。
  3. 你好 B。

详细描述:

  1. 服务端处于监听状态listen
  2. 客户端发起握手请求(你好,我想要连接了哦),状态变为syn_sent
  3. 服务端收到请求后随后发起应答请求(你好,可以的),状态变为syn_received
  4. 客户端收到请求返回的ack,随后回复服务端(应答的应答:嗯,好的。),状态变为established
  5. 服务端收到客户端应答,状态变为established

问题:

  1. 为什么是三次握手,不是两次或者四次?
  2. 三次握手可以携带数据吗?
  3. 半连接是什么?
  4. SYN攻击是什么?

1,为什么是三次握手,不是两次或者四次?

两次: 客户端发起请求,服务端返回。客户端可以确认服务端ok,但是服务端没有收到客户端确认ack,没法确定客户端ok。

四次:经过三次握手,其实可认为双方都已经确认ok。如果不能确认,就算四次握手,十次握手也不能确定。

2,三次握手可以携带数据吗?半连接是什么? SYN攻击是什么?

前两次握手是不能携带数据的。因为服务端在收到syn后,已经进入半连接状态,会将该链接放入半连接队列里面,此时开始分配资源和内存。而如果存在大量的非法连接请求,携带大量数据(根本不用等服务端返回)。会造成服务端大量资源被占用无法释放。

第三次握手是可以携带数据的。

3.3.3 TCP的四次挥手

到了说再见的时候了。

简要流程:

  1. 客户端:服务端,我想断开了
  2. 服务端:好的,客户端
  3. 服务端:客户端,我也想断开了
  4. 客户端:好的,服务端

详细流程: 当①②走完后,此时如果服务端不在发送③步,那么系统内核会根据一个超时时间来关闭该连接。

当③④走完后,客户端不会立即计入closed状态,而是进入time_wait。

有两个原因:

  1. 需要等到报文在网络的最大存活时间,让第④步到达服务端。有可能服务端没收到,那么会重新发送FIN到客户端。
  2. 还需要等待接收服务端一些延时到达的数据包

在等待2MSL(max segment life,一般为30s、1、2分钟)后,无论如何,客户端都会关闭了。tcp基于ip,ip中有TTL(time to life)域就是网络包的存活时间。

3.3.4 TCP的应答方式

tcp并不是发起一个请求,必须等到该请求的应答返回才去发送下一个。这样效率太低了。

累计确认/累计应答:

发送端会一次发送多个包,然后等待接收端的应答一起确认。 当然,发送端不能无限制的发送,接收端也不可能无限制接收,所以就有了发送窗口和接收窗口。

3.3.5 TCP的滑动窗口

发送端窗口:

  1. 发送且已经确认 已处理,此时不算入窗口内
  2. 发送待确认 在窗口内
  3. 未发送可以发送 在窗口内
  4. 不可发送 不在窗口内

接收端窗口:

  1. 接收已确认 尚未被应用程序消费,在窗口内,
  2. 带接收 在窗口内
  3. 不可接收 不在窗口内

滑动窗口原理:

注意: 滑动窗口是一种控制流量的方式。 发送端的窗口大小是有接收端来决定的。

从三次握手到中间的数据传输,接收端都会通过ack告诉发送端,接收端窗口的大小(也就是能处理数据包多少的能力)。

想象发送端的数据包都在一个队列里面(都已经编号),只要接收端返回ACK通知哪个包已经被成功接收,那么发送端就会确认改包。从而发送端窗口就会往右边移动,至于移动多少呢? 这就跟接收端能接收多少有关了(接收窗口)。 发送端可用窗口大小=接收端窗口-发送尚未确认的包段大小

如果程序一直没有处理包,当接收端窗口满了的时候,那么可用窗口就=0。那么此时发送端不会再发送数据。

但是会有零窗口机制,发送端会去探测接收端是否有空窗口使用。如果有则继续发送。

滑动窗口示意图:

4、socket套接字

socket是对tcp和udp的再一次封装。 应用层只需要通过socket就能完成网络连接(不用关心三次握手、四次挥手的具体的操作)。

更高层次理解:

socket是实现端对端的通信。中间经过多少网络、路由器它都不知道。因此,它只能设置网络层和传输层的参数:

  • 网络层:设置ip。是ip4还是ip6
  • 传输层:除了设置端口号,是tcp还是udp。 tcp基于数据流,因此是SOCKET_STREAM, udp基于数据报传输,是SOCKET_DGRAM。

4.1 基于tcp的socket调用过程

  1. 服务端创建监听socket,调用bind()函数为socket绑定ip和端口。
  2. 服务端调用socket的 listen函数,进入listen状态
  3. 服务端调用socket的 accept函数,如果有连接则会返回,如果没有则阻塞,直到客户端发起连接。注意 此时发回的已连接socket与上面监听的socket是两个对象
  4. 客户端通过创建、bind socket后,发起连接connect函数(通过三次握手)
  5. 服务端accept收到,在服务端返回一个新的socket对象。
  6. 至此,客户端与服务端可以通过socket来 读、写数据了

文件描述符

每一个进程会有一个数组用来保存所访问的过文件,而文件描述符fd则是这个数组的下标。fd是一个整数。

4.2 基于udp的socket调用过程

udp不需要建立连接,所以不会有三次握手。

服务端不用为每个连接维护一个socket,而是只要一个socket即可实现一对多的通信。 一个服务端socket 对应 多个客户端。

调动过程:

  1. 服务端创建socket,调用bind函数绑定ip和端口。
  2. 客户端创建socket,调用bind函数。
  3. 直接调用sendTo发送数据到服务端
  4. 服务端调用recvFrom接收数据

4.3 服务端是如何做到维护大量tcp连接的?

基本原理: 需要用到 多进程、多线程

通过epoll机制(基于红黑树)回调 来解决C10K 的问题。

一个线程可以维护多个socket连接。 socket在内核中相当打开了文件,也就对应一个文件描述符。利用epoll机制,注册callback(而非轮询),只要socket对应的文件描述符有变化,那么就会主动回调到处理线程。那么线程就能处理了。

当然还要多进程方式。 通过fork一个子进程来处理。

5、http与https

5.1 http

5.1.1 http请求前准备

在构建完http请求后,不是直接就开始发送的。而是要先建立tcp连接,经过三次握手后,经由socket才到传输层去发送请求。

5.1.2 http的请求构成

http请求分为:

  • 请求行 包含方法、url、http版本
  • 请求头 key-value值 如keep-alive
  • 请求体 正文内容

1,请求行

get方法是从服务端获取某种资源。 post方法则是告诉服务端一些信息。如:我要买什么,卖多少等

2,请求头中 缓存:

客户端访问一些不会经常变动的资源(静态资源),一般会有缓存。服务端首先会判断处于缓存期间,且该资源没有变动。则直接返回缓存。否则,会访问最新服务器拉取资源。

5.1.3 http的响应构成

http响应:

  • 响应行 返回状态码
  • 响应头 key-value
  • 响应体 返回的内容
5.1.4 http1.1 与http2.0的区别

http1.1之前,如果有多个请求是串行执行请求的。 即:请求1-返回1-请求2-返回2-请求3-返回3。

http2.0后,会把三个请求同时发送和返回,通过把多个请求分散到多个流中,并且每个请求的数据在tcp层切分为帧,每个镇是会被打乱传输。这样就解决阻塞问题。

头压缩,通过在双端建立索引表。把公共的key-value,只穿索引号,减少头部空间。

另外,也不需要http1.x中的通过pipleline机制维护的多个tcp连接,来实现并行请求。

5.1.5 google的QUIC

google 基于udp实现了类似于tcp一样的连接、多路复用、重试、流量控制等协议。

5.2 https

https是建立在tls套件之上的http,加密传输。 利用非对称加密用来验证证书的安全性、合法性,在通过对称加密来进行数据传输。

5.2.1 SSL 与 TLS
  • SSL: secure socket layer。安全套阶层
  • TLS:transport layer security 传输层安全协议。 用来替换SSL加密套件。
5.2.2 对称加密与非对称加密

对称加密:发送方和接收方都是同一个把密钥。特点是加密效率高。密钥容易泄露,不安全。 非对称加密: 发送方自己保留私钥,用私钥进行加密,接收方(可能有多个)用公钥进行解密。特点加密慢。

因此一般采用组合方式: 对称加密的私钥 通过非对称加密来传输。

5.2.3 CA证书

证书里面包含了 公钥、证书的申请者、发布者、日期、有效日期等信息。

第三方公司的公钥不能直接放到网站上让app自己去下。 这样不可靠。而是通过生成证书的方式来对外部调用者提供。

因此,我只要能证明第三方公司的CA合法,那也就认为它的公钥合法。为了给第三方公司的证书作证明,需要权威CA机构来给第三方公司的证书做签名保证(如:这个身份证是派出所签了名的啊,是合法的。)。

因此,我们需要证明该CA机构合法(我要证明派出所是合法的。 这是一个不断CA的过程,直到顶层CA,如国务院颁发的? 哦,那就没问题了),这个过程一般是从系统自带的CA库中去查找。再用该机构的公钥去解密改机构的签名保证,从而认为第三方公司的证书合法,最终认为第三方公司的公钥合法。

然后我们利用公钥和一些随机数规则来生成会话用的对称加密私钥。有了私钥就可以安全、愉快的进行数据传输了。

5.2.4 https的加密过程

前提: 所有的加密操作都是建立在tcp建立连接以后。

  • c–>s: 我使用https加密传输,我的加密套件是tls版本xxx等信息,给你一个随机数。
  • s–>c: 我也使用https,我的加密条件是tls版本xx等信息 ,也给你一个随机数。
  • s–>c:这是我的证书xx,你验证下吧
  • c:通过ca验证证书可靠。拿到公钥。在生成一个pre-master随机数,通过公钥传给s。
  • c–>s: 计算得到私钥(自己的随机数+对端的随机数+pre-master随机数),我们以后就用这个私钥传输吧。
  • c–>s: 利用私钥测试下消息发送
  • s–>c: 计算得到私钥,可以啊。我们以后就这样沟通了。

后面,就是http的传输过程了。

6、dns 与 httdns

  • dns:

域名解析系统,即把域名解析成ip。 它首先会从本地系统的缓存中去读取,然后就近的dns服务器获取,最终去主域名服务器获取。每一层都有缓存。如果更新不及时就会引发ip更新不及时的问题。

缺点:

  1. 缓存时间无法确定。设置过长导致ip更新不及时,设置过短导致命中不了缓存,从而请求时间增加。
  2. 域名劫持 中间可能返回其他网站的ip,发生劫持。
  3. 解析过长不可控,无法快速解析ip
  4. 一次只能解析一个域名
  • httpdns:

通过自己的服务器来管理域名与ip的对应关系。 app在启动的时候从后台拉取映射表数据到本地,然后通过跑马拿到最快的ip地址(或者服务端直接返回就近的ip地址),从而实现替换。

一次可以解析多个域名。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

一、架构师筑基必备技能

1、深入理解Java泛型
2、注解深入浅出
3、并发编程
4、数据传输与序列化
5、Java虚拟机原理
6、高效IO
……

在这里插入图片描述

二、Android百大框架源码解析

1.Retrofit 2.0源码解析
2.Okhttp3源码解析
3.ButterKnife源码解析
4.MPAndroidChart 源码解析
5.Glide源码解析
6.Leakcanary 源码解析
7.Universal-lmage-Loader源码解析
8.EventBus 3.0源码解析
9.zxing源码分析
10.Picasso源码解析
11.LottieAndroid使用详解及源码解析
12.Fresco 源码分析——图片加载流程

在这里插入图片描述

三、Android性能优化实战解析

  • 腾讯Bugly:对字符串匹配算法的一点理解
  • 爱奇艺:安卓APP崩溃捕获方案——xCrash
  • 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
  • 百度APP技术:Android H5首屏优化实践
  • 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
  • 携程:从智行 Android 项目看组件化架构实践
  • 网易新闻构建优化:如何让你的构建速度“势如闪电”?

在这里插入图片描述

四、高级kotlin强化实战

1、Kotlin入门教程
2、Kotlin 实战避坑指南
3、项目实战《Kotlin Jetpack 实战》

  • 从一个膜拜大神的 Demo 开始

  • Kotlin 写 Gradle 脚本是一种什么体验?

  • Kotlin 编程的三重境界

  • Kotlin 高阶函数

  • Kotlin 泛型

  • Kotlin 扩展

  • Kotlin 委托

  • 协程“不为人知”的调试技巧

  • 图解协程:suspend

在这里插入图片描述

五、Android高级UI开源框架进阶解密

1.SmartRefreshLayout的使用
2.Android之PullToRefresh控件源码解析
3.Android-PullToRefresh下拉刷新库基本用法
4.LoadSir-高效易用的加载反馈页管理框架
5.Android通用LoadingView加载框架详解
6.MPAndroidChart实现LineChart(折线图)
7.hellocharts-android使用指南
8.SmartTable使用指南
9.开源项目android-uitableview介绍
10.ExcelPanel 使用指南
11.Android开源项目SlidingMenu深切解析
12.MaterialDrawer使用指南
在这里插入图片描述

六、NDK模块开发

1、NDK 模块开发
2、JNI 模块
3、Native 开发工具
4、Linux 编程
5、底层图片处理
6、音视频开发
7、机器学习

在这里插入图片描述

七、Flutter技术进阶

1、Flutter跨平台开发概述
2、Windows中Flutter开发环境搭建
3、编写你的第一个Flutter APP
4、Flutter开发环境搭建和调试
5、Dart语法篇之基础语法(一)
6、Dart语法篇之集合的使用与源码解析(二)
7、Dart语法篇之集合操作符函数与源码分析(三)

在这里插入图片描述

八、微信小程序开发

1、小程序概述及入门
2、小程序UI开发
3、API操作
4、购物商场项目实战……

在这里插入图片描述

全套视频资料:

一、面试合集
在这里插入图片描述
二、源码解析合集

在这里插入图片描述
三、开源框架合集

在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值