Android常用的网络协议串讲
1.前言
现在社会处处都在使用网络,例如,浏览网页、即时聊天以及手机支付等。可是,网络对大部分人而言只是个名词,只知道插上网线、开启数据流量就可以用网络了。但是,作为移动开发人员,不了解网络组成还是有点心虚的。我根据看到的文章,大概地讲一下认识的思路,有错的希望大家指出。
2.网络协议架构
Models.png网络主要有两种模型可供参考,最基本的是OSI七层参考模型,从底层到表层主要包括(详见羽若其的博客):
- 物理层:连接网络的硬件设备,就是将电脑连接起来的物理手段,如光纤。
- 数据链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能,如32位和64位计算机,他们的解码方式是不一样的,数据链路层就规定了二进制数据的解读方式。
- 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择。网络层建立了主机之间的通信,它在网络层引入了一套地址机制:网络地址,简称网址(IP地址)。通过IP地址,可以找到任意一台计算机。
- 传输层:定义传输数据的协议端口号,以及流控和差错效验,定义了端口和端口之间的通信,使不同的应用程序能够接收到自己所需要的数据。
- 会话层:包括建立、管理、终止会话,使应用程序之间的通信实现自动寻址,自动收发数据。
- 表示层:数据的表示、安全、压缩。比如要用基于Unix系统的MAC电脑给PC机发送数据,表示层为我们解决了通信间语法的问题。
- 应用层:网络服务与最终用户的一个接口。比如不同的文件类型要用不同的应用程序打开,应用层中就规定了不同应用程序的数据格式。
但是,七层参考模型过于详细,所以把因特网TCP/IP协议族内的所有协议进行归类,抽象为右图所示的四层参考模型。
3.各协议串讲
TCP/IP Model.png网络互连层主要包括三个协议:ICMP、IGMP和IP。其中IP协议是为计算机网络相互连接进行通信而设计的协议。
传输层以IP协议为基础,有两大协议:TCP、UDP,主要解决数据如何在网络中传输,详细可参考sunshine静的博客。
TCP(传输控制协议) | UDP(用户数据报协议) |
---|---|
面向连接,发送数据前建立连接 | 无连接,发送数据前不建立连接 |
逻辑通信信道是全双工的可靠信道,传送数据(理论上)无差错、不丢失、不重复,且按序到达 | 不可靠信道,不提供差错恢复和数据重传,尽最大努力交付,但不保证可靠交付 |
面向字节流,把数据看成一连串无结构的字节流 | 面向报文,没有拥塞控制(当网络拥塞时,不会使源主机的发送速率降低,适合实时应用) |
点到点连接 | 支持一对一、一对多、多对一和多对多的交互通信 |
首部开销大,20个字节 | 首部开销小,只有8个字节 |
应用层基于TCP协议可以划分为:HTTP、HTTPS两种协议,主要解决如何包装数据和识别数据。由于HTTPS是HTTP的安全版,两个协议有些共同点:客户端每次请求,服务端都得响应;请求结束后,会主动释放连接,所以“无状态”。
HTTP(超文本传输协议) | HTTPS(加密的超文本传输协议) |
---|---|
调用套接字接口(Socket),明文传输,不安全 | 被嵌入加密套接字层(SSL),密文传输,安全 |
端口80 | 端口443 |
不需要证书 | 需要到CA申请证书 |
4.Socket与长连接
Socket本身并不是协议,而是一个针对TCP或UDP的调用接口(API),使用它才能按照底层协议进行网络通信。它包含进行网络通信必需的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远程主机的IP地址,远程进程的协议端口。
Socket虽不占层级,但起到连接应用层和传输层的作用。这种设计可以解决多应用导致多个传输层连接并发时,区分不同网络连接的通信,防止数据传输的冲突。
Socket使用TCP建立长连接 | 使用HTTP建立长连接 |
---|---|
双方互相发送数据 | 服务器只能被动接受客户端请求予以回应 |
通信时长为连接建立到断开 | 短连接,无通信时长,得不断发送请求 |
系统为了节约资源,会关闭长时间不用的连接;服务器为了区分用户是否在线,也会设置过期时间。需每隔一段时间,发送空包表明仍需连接 | 建立连接需耗资源,越频繁地询问服务器的操作,越耗资源 |
5.三次握手和四次挥手
Handshake.png现在知道使用TCP协议传数据需先建立连接,这个过程通常称为“三次握手”:
- 第一次握手:客户端尝试连接服务器,向服务器发送SYN(同步序列编号Synchronize Sequence Numbers)包(Seq=X),客户端进入SYN_SENT状态,等待服务器确认。
- 第二次握手:服务器接收客户端SYN包并确认(Ack=X+1),同时向客户端发送一个SYN包(Seq=Y),即SYN+Ack包,此时服务器进入SYN_RECEIVED状态。
- 第三次握手:客户端收到服务器的SYN+Ack包,向服务器发送确认包(Ack=Y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
连接一旦建立,除非有一方主动关闭连接,否则理论上会一直保持下去。关闭的流程,与建立流程很类似:
- 第一次挥手:客户端向服务器发起中断请求,向服务器发送FIN包(seq=u),客户端进入FIN_WAIT状态,等待服务器确认。
- 第二次挥手:服务器接收客户端FIN包,但数据可能没发送完,先只确认(ack=u+1),同时向客户端发送一个ACK包(seq=v),此时服务器进入CLOSE_WAIT状态。
- 第三次挥手:服务器数据传送完毕,向客户端发送FIN包(seq=w),服务器进入LAST_ACK状态,等待客户端确认。
- 第四次挥手:客户端接收服务器FIN包,在确认(ack=w+1)的同时,向服务器发送一个ACK包(seq=u+1)。由于担心网络影响ACK包的传递,为重发丢失的ACK报文,客户端进入TIME_WAIT状态。服务器收到ACK包后,进入CLOSED状态,客户端等待2MSL仍没有收到服务器反馈,也进入CLOSED状态,完成四次挥手。
由于Socket连接通常是基于TCP协议的,所以建立连接的过程也符合“三次握手”,步骤为:服务器监听、客户端请求和连接确认。
6.总结
网络协议很多,纵向上是一层套一层,横向上则是种类繁多,为不同情况专门设计。所以了解协议对理解应用场景很有启发,也有助于解读相应的通信框架。