一、前言
Alamofire 是用 swift 写的一套网络请求三方库,相当于 OC 中的 AFNetWorking。在开始学习 Alamofire 之前,先来复习一下网络的一些基础知识,这样可以更有助于我们学习理解这个网络请求框架。
二、OSI 七层网络架构
1、概览
互联网协议 按照功能不同分为 OSI 七层或 tcp/ip 五层或 tcp/ip 四层。每一层都运行不同的协议。如下图:
每层的对应的功能与协议如下表格:
OSI七层网络模型 | TCP/IP四层概念模型 | 功能 | 对应的协议 |
---|---|---|---|
应用层(Application) | 应用层 | 文件传输,电子邮件,文件服务,虚拟终端 | HTTP、TFTP, FTP, NFS, WAIS、SMTP、Telnet |
表示层(Presentation) | 应用层 | 数据格式化,代码转换,数据加密 | Telnet, Rlogin, SNMP, Gopher |
会话层(Session) | 应用层 | 解除或建立与其他接点的联系 | SMTP, DNSr |
传输层(Transport) | 传输层 | 提供端对端的接口 | TCP, UDP |
网络层(Network) | 网络层 | 为数据包选择路由 | SMTP, DNSr |
数据链路层(Data Link) | 网络接口层 | 传输有地址的帧,错误检测功能 | FDDI, Ethernet, Arpanet, PDN, SLIP, PPP |
物理层(Physical) | 网络接口层 | 以二进制数据形式在物理媒体上传输数据 | IEEE 802.1A, IEEE 802.2 到 IEEE 802.11 |
客户端发送请求到接收端的过程:
发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。
这种把数据信息包装起来的做法成为封装。
2、具体介绍
1)物理层(Physical)
物理层就是通过光纤、电缆等进行连接,基于电器特性发送高低电压(电信号),高电压对应数字 1,低电压对应数字 0,传输一堆 001010100 的二进制位。
2)数据链路层(Data Link)
只是物理层的单纯的电信号 0 和 1 是没有意义的,必须规定电信号多少位一组,每组什么意思才行,数据链路层就是来对电信号来做分组的。数据链路层在不可靠的物理介质上提供可靠的传输。
该层的作用包括:
物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。在这一层,数据的单位称为帧(frame)。数据链路层协议的代表包括:SDLC、HDLC、PPP、STP等。
3)网络层(Network)
网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息- -源站点和目的站点地址的网络地址。网络层主要设备是路由器。
网络层还可以实现拥塞控制、网际互连等功能。在这一层,数据的单位称为数据包(packet)。网络层协议的代表包括:IP、IPX、RIP、OSPF 等。
4)传输层(Transport)
网络层的 ip 帮我们区分子网,以太网层的 mac 帮我们找到主机,那么如何标识这台主机上的应用程序,那就需要端口,端口就是应用程序与网卡关联的编号。
传输层功能就是建立端口到端口的通信。端口范围 0-65535,0-1023 为系统占用端口。
(1)TCP 协议:
可靠传输,TCP 数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常 TCP 数据包的长度不会超过IP数据包的长度,以确保单个 TCP 数据包不必再分割。
源端口和目的端口:
一个 IP 地址和端口的组合称为“套接字”或“端点”。
所以 IP 协议中的源 IP 地址和目的地址,组成了“一对”套接字(发送端的套接字和接收端的套接字)。序号:
每一个“TCP 报文段中的第一个字节”都会被赋予一个序号(递增)。根据 控制标志 中的 SYN 是否为 1,序号表达不同的含义:
SYN = 1:当前为连接建立阶段,此时的序号为初始序号(ISN)。当数据传输正式开始时,数据的第一个字节的序号为 ISN + 1;
SYN = 0:当前报文段中,数据部分的第一个字节的序号。确认号(TCP返回报文使用):
确认号也称 ACK 号或 ACK 字段。确认号包含的值为:“确认号的发送方”希望接收的下一个序列号。(即最后接收成功的序列号 +1)一旦连接建立成功,ACK 值一直为1。数据偏移量:
TCP 报文段的首部长度,单位是 word(4字节)。字面含义是:TCP 报文段的数据的起始处,距离 TCP 报文段的起始处 的偏移量。4 个字节最大能表示的数字是 15,所以首部最大 60 字节。保留字段:
预留作为后续用途,必须是 0。控制标志:
一共有 6 个控制标志,其中 SYN/ACK、FIN/ACK 主要用于连接的建立、断开阶段。
URG: 当置为 1 时,表示 紧急指针 字段有效;
ACK: 确认 序号 字段有效;
PSH: 接收方应立即把这个报文段交给应用层;
RST: 重建连接;
SYN: 同步序号,用于建立连接;
FIN: 发送端不再发送数据;窗口大小:
允许对方发送的数据量。告诉对方自己缓冲区还能容纳多少字节,用来控制对方发送数据的速度。校验和:
发送端对 TCP 首部、数据进行 CRC 运算得出的结果。接收端收到数据后,对接收到的 TCP 报文段的首部、数据进行CRC 运算,并跟 TCP 首部中的校验和进行对比,确保数据在传输过程中没有损坏。紧急指针:
仅在 URG=1 时才生效,它的值是一个偏移量,和序号字段中的值相加得到紧急数据最后一个字节的序号。
- 可选字段:
最常见的可选字段是 MSS(Maximum Segment Size),表示最长报文大小,通信双方通常在连接的第一个报文段中指明这个选项。(只能出现在 SYN 报文中)
TCP 的三次握手和四次挥手:
(1)三次握手:
第一次握手: 建立连接时,客户端发送 syn 包(syn=x)到服务器,并进入
SYN_SENT
状态,等待服务器确认;SYN: 同步序列编号(Synchronize Sequence Numbers)。
第二次握手: 服务器收到syn包,必须确认客户的 SYN(ack=x+1),同时自己也发送一个 SYN 包(syn=y),即 SYN+ACK 包,此时服务器进入 SYN_RECV
状态;
第三次握手: 客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=y+1),此包发送完毕,客户端和服务器进入 ESTABLISHED
(TCP 连接成功)状态,完成三次握手。
(2)四次挥手:
1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为 seq=u(等于前面已经传送过来的数据的最后一个字节的序号加 1 ),此时,客户端进入
FIN-WAIT-1
(终止等待 1)状态。 TCP 规定,FIN 报文段即使不携带数据,也要消耗一个序号。
2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1 ,并且带上自己的序列号 seq=v ,此时,服务端就进入了 CLOSE-WAIT
(关闭等待)状态。TCP 服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个 CLOSE-WAIT
状态持续的时间。
3)客户端收到服务器的确认请求后,此时,客户端就进入 FIN-WAIT-2
(终止等待 2 )状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1 ,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为 seq=w ,此时,服务器就进入了 LAST-ACK
(最后确认)状态,等待客户端的确认。
5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1 ,而自己的序列号是 seq=u+1 ,此时,客户端就进入了 TIME-WAIT
(时间等待)状态。注意此时TCP连接还没有释放,必须经过 2∗∗MSL (最长报文段寿命)的时间后,当客户端撤销相应的 TCB 后,才进入 CLOSED
状态。
6)服务器只要收到了客户端发出的确认,立即进入 CLOSED
状态。同样,撤销 TCB 后,就结束了这次的 TCP 连接。可以看到,服务器结束 TCP 连接的时间要比客户端早一些。
面试时经常问的问题:
1、为什么 TCP 建立连接需要三次握手,而非两次?
为了实现可靠传输,发送方和接收方始终需要同步( SYNchronize )序号。 需要注意的是, 序号并不是从 0 开始的, 而是由发送方随机选择的初始序列号 ( Initial Sequence Number, ISN )开始 。 由于 TCP 是一个双向通信协议, 通信双方都有能力发送信息, 并接收响应。 因此, 通信双方都需要随机产生一个初始的序列号, 并且把这个起始值告诉对方。
过程如下图:
2、为什么 TCP 断开连接需要四次挥手,而非两次或三次?
(2)UDP 协议:
不可靠传输,”报头”部分一共只有 8 个字节,总长度不超过65,535 字节,正好放进一个 IP 数据包。
TCP 与 UDP 的区别:
TCP 是可靠通信协议, 而 UDP 是不可靠通信协议。
TCP 的可靠性含义: 接收方收到的数据是完整, 有序, 无差错的。
UDP 不可靠性含义: 接收方接收到的数据可能存在部分丢失, 顺序也不一定能保证。
TCP 协议为了实现可靠传输, 通信双方需要判断自己已经发送的数据包是否都被接收方收到, 如果没收到, 就需要重发。 为了实现这个需求, 很自然地就会引出序号(sequence number) 和 确认号(acknowledgement number) 的使用。
发送方在发送数据包(假设大小为 10 byte)时, 同时送上一个序号( 假设为 500),那么接收方收到这个数据包以后, 就可以回复一个确认号(510 = 500 + 10) 告诉发送方 “我已经收到了你的数据包, 你可以发送下一个数据包, 序号从 510 开始” 。
这样发送方就可以知道哪些数据被接收到,哪些数据没被接收到, 需要重发。
5)会话层(Session)
这一层也可以称为会晤层或对话层,在会话层及以上的高层次中,数据传送的单位不再另外命名,而是统称为报文。会话层不参与具体的传输,它提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制。如服务器验证用户登录便是由会话层完成的。
6)表示层(Presentation)
这一层主要解决拥护信息的语法表示问题。它将欲交换的数据从适合于某一用户的抽象语法,转换为适合于 OSI 系统内部使用的传送语法。即提供格式化的表示和转换数据服务。数据的压缩和解压缩, 加密和解密等工作都由表示层负责。
7)应用层(Application)
应用层为操作系统或网络应用程序提供访问网络服务的接口。应用层协议的代表包括:Telnet、FTP、HTTP、SNMP 等。
以上的总结参考了并部分摘抄了以下文章,非常感谢以下作者的分享!:
1、太白金星的《网络协议篇(osi七层协议)》
2、上野 宣 的《图解http》
3、Red_Code的《TCP协议详解》
4、程序猿小卡的《TCP入门与实例讲解》
5、青柚_的《TCP的三次握手与四次挥手理解及面试题(很全面)》
转载请备注原文出处,不得用于商业传播——凡几多
网友评论