Android 中网络协议的使用

在Android中,有很多网络协议,在这些协议的正确使用下产生了很多优化:直播推流优化,图片下载优化等。我们首先先从介绍计算机网络开始,到具体的Android中协议的使用。

计算机网络模型

一般来说,我们网络模型分为七层,四层,五层。通用来说,我们其实使用最多的是五层互联网协议

如图所示:

这里面其实最重要的还是运输层,网络层。关于其他的我们只是简单的介绍一下:(以五层为标准)

应用层:为用户进程直接提供服务,有HTTP/HTTPS协议。也有支持文件传送的FTP协议,DNS,POP3,SNMP,Telnet,支持电子邮件的SMTP协议等。

运输层:主要是为两个主机的进程提供服务,但一个主机也可以有多个进程进行通信,用的也是传输层的协议,具体有:TCP或者UDP

网络层:主要是为两台主机提供通信服务,经过路由再转发。

数据链路层:负责将网络层交下来的 IP 数据报封装成帧,并在链路的两个相邻节点间传送帧,每一帧都包含数据和必要的控制信息(如同步信息、地址信息、差错控制等)。

物理层:确保数据可以在各种物理媒介上进行传输,为数据的传输提供可靠的环境。

数据链路层

数据链路层主要是封装成帧,透明传输和差错检测,在封装的时候主要是通过SOH(帧起始标志)和EOT(帧结束标志)来封装,但如果有分不清头尾的情况我们再定义一个转义字符:ESC来封装。 而差错检测则是通过循环冗余校验CRC来进行检测。

在数据链路层中,用的最广泛的是PPP协议,将 IP 数据报封装到串行链路。链路层其实是通过 Mac 地址来识别需要发送数据的目标节点

MAC地址也就是物理地址,用于在网络中唯一标识一个网卡,一台设备若有多个网卡,则每个网卡都会有一个唯一的 MAC 地址。MAC地址为 48 位的(6 个字节),通常表示为 12 个 16 进制数,每两个 16 进制数之间用冒号隔开,如 08:00:20:0A:8C:6D,前 3 字节为组织机构唯一标识(OUI)

网络层

一般来说我们用IP协议或者ARP协议来进程传输,或者是路由。我们先大概了解一下格式和作用即可,其他的以后补充

IP协议传输IP数据报,通过IP地址进行路由或者传输。 格式如下:

ARP协议是对IP协议的解释,也就是把IP地址转换成链路层能够感知的MAC地址,内部维护一个缓存表,存储了本局域网内各主机和路由器的 IP 地址与 Mac 地址的映射关系。

运输层

最重要的运输层,也是我们学习的重点,关于在Android中有很多关于这方面的操作,因为我们不仅仅是在写应用,也需要去做一些交互

直接进入正题,讲解TCP和UDP协议

TCP,UDP协议是运输层的重要组成,主要负责向两个主机的进程提供服务,发送数据,TCP连接需要有三次握手,断开需要四次挥手。具体原因我们马上谈谈,我们先说有哪三次握手,哪四次挥手。

三次握手

建立的连接是两个主机的进程,所以其实我们一般称之为客户端,服务端,客户端向服务器进行请求操作。

有一些参数事先说明:

SYN: 同步位

seq:发送序号

ACK:确认位

ack:确认序号

FIN(Finish):控制位

因为TCP是全双工的(就是双方都可以同时发数据),这就导致和断开的一些问题,我们先看看如何建立连接:

首先客户端向服务的发送请求连接的报文(请问是否同意连接):SYN = 1 序号seq为x

服务端接收到请求以后如果同意建立连接,则发送确认报文段(同意连接):SYN = 1, ACK = 1,ack = x + 1; 并且选一个发送序号:seq = y

客户端收到以后,发最后的确认(代表已经收到你的回话):ACK = 1, ack = y + 1(对seq = y的确认);ACK 报文段可以携带数据也可以不携带,如果不携带则该序号不被消耗,下一个数据报文段的序号仍然是 seq = x + 1。之后进入ESTABLISHED(连接状态)

服务端收到以后客户端发的最后确认进入连接状态。

如图所示:

四次挥手

断开连接同样需要相似的一些步骤,只不过会多一步,一会会说为什么多一步

同样的道理需要这个过程,假设客户端先关闭连接,此时需要发送连接释放报文段:首部终止控制位 FIN 为 1,seq = u.其中 u 等于前面传送过的数据的最后一个字节的序号加 1 。之后 A 进入 FIN-WAIT-1状态

服务端收到连接释放报文段后立即发出确认,确认号 ack = u + 1,序号 seq = v ,其中 v 等于前面传送过的数据的最后一个字节的序号加 1 。之后 服务端进入 CLOSE-WAIT(关闭等待)状态

客户端收到来自服务端的确认以后进入FIN-WAIT-2(终止等待 2)状态,等待服务端发出连接释放报文段。

若高层应用进程已经没有数据要发送,则通知服务端释放 TCP 连接。此时 B 发出释放连接报文段:首部终止控制位 FIN 为 1,序号 seq = w(在半关闭状态下 服务端可能又发送了一些数据),另外还需要重复上次已经发送过的确认号 ack = u + 1。之后 服务端 进入 LAST-ACK(最后确认)状态;

客户端收到服务端的连接释放报文段后,发出最后确认:ACK 为 1,确认号 ack = w + 1,序号 seq = u + 1,然后进入 TIME-WAIT(有时间限制的等待)状态;

服务端收到来自客户端的最后确认后进入 CLOSED(关闭)状态;

客户端经过 2 倍的 MSL(Maximum Segment Lifetime,最长报文段寿命)后,才进入 CLOSED 状态。

说完了这么多,我们现在来说一说为什么要有四次挥手,因为TCP连接是全双工的! 也就是说,发送方向接收方向独立关闭的

四次挥手确保双方的发送方向分别独立关闭

最后,我们来探讨一下关于Android中的一些网络协议