http - 基础总结 - 隐藏
前言
一、OSI (国际标准化组织)的组织模型
二、TCP/IP 分层
三、TCP和UDP的区别
四、socket
五、TCP的三次握手
六、TCP的四次挥手
作为客户端开发人员,平时常用的网络请求框架,比如ios端的AFNetworking、Alamofire,甚至最早之前的ASIHttpRequest,再比如android端的okhttp等。它们的底层都离不来http/https。为了更好的去深入理解网络请求。我们就对http和https进行的具体的分析,由于网络协议以及底层的东西太多了,所以我们只分析我们需要掌握和认知的东西。
一、OSI (国际标准化组织)的组织模型
OSI定义了网络互连的七层框架:
1、应用层 - 为应用程序提供服务
常见的应用层的网络服务协议有:HTTP、HTTPS、FTP等。
这层还有DNS(Domain Name System) 域名系统
2、表示层 - 数据格式转化、数据加密
3、会话层 - 建立、管理和维护会话
4、传输层 - 建立、管理和维护端到端的连接
TCP、UDP就是在这一层
5、网络层 - IP选址及路由选择
IP协议在这一层
6、数据链路层 - 提供介质访问和链路管理
7、物理层
在七层框架的基础上,再看一下TCP/IP五层模型
1、应用层 - 其实就包含了7层模型中的应用层、表示层、会话层
2、传输层
3、网络层
4、数据链路层
5、物理层
通过对OSI模型的大致了解,我们可以确定HTTP、HTTPS 是建立在传输层和网络层之上的,也就是说它们是基于TCP/IP协议的。
二、TCP/IP 分层
首先需要搞清楚,TCP协议和IP协议与TCP/IP协议的联系,TCP/IP协议是一个协议簇。里面包括很多的协议,TCP协议和IP协议只是其中的一个。之所以命名为TCP/IP协议,因为TCP、IP协议是两个很重要的协议,就用他俩命名了。
通过上面的了解,我们知道TCP就是传输层的协议,IP就是网络层的协议。那么具体的来说TCP/IP分为四层,物理层我们就不关注了,如图所示:

1、应用层
这一层就像上OSI定义的一样,它决定了向用户提供应该服务时通信的活动。比如有FTP(文本传输协议)、HTTP(超文本传输协议)、DNS(域名系统)、Telnet(远程登录可以)等。
2、传输层
这一层提供处于网络连接中的两台计算机之间的数据传输。其中有两个性质不同的协议:TCP和UDP。
下面会具体分析这2种协议的区别。
3、网络层
网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层通过IP协议把各种数据包传送给对方。
这层包括 IP(网络协议)、ICMP(网络控制信息协议)。
4、链路层
用来处理连接网络的硬件部分。包括控制操作系统、设备驱动、网卡等。
这层包括 ARP(地址解析解析)、RARP(反向地址解析协议)
三、TCP和UDP的区别
首先相同点是:TCP 和 UDP 都是传输层协议。
不同点:
TCP 是传输控制协议,提供的是面向连接,可靠的字节流服务。客户端和服务端交换数据之间,必须先在双方建立之间一个TCP连接(经过3次握手),然后才能传输数据。并且提供超时重发,丢弃重复数据,校验数据,流量控制等功能。从而保证数据能从一端传到另一端。
UDP 是用户数据报协议,是一个简单的面向数据报的运输协议。它不提供可靠性,只是把应用程序传给IP层的数据报发送出去。它在传输数据之前,不需要建立连接,也没有超时重复等机制,所以它的传输速度很快。
TCP的包头最少20个字节,而UDP信息包的标题很短,只有8个字节。
总结一下不同点:
(1)TCP基于连接,UDP不用建立连接
(2)TCP和UDP的包头结构不同,TCP包头最少20个字节,UDP只有8个字节。
(3)TCP能保证数据正确性,UDP无法保证,可能丢包
(4)TCP能保证数据的顺序,UDP无法保证。
(5)TCP对系统资源要求比较多,UDP责比较少。
四、socket
先来回顾一下什么是socket,在我们平时的开发过程中,我们经常用socket来即时通讯,通过socekt的接口,我们可以实现两个端之间的通信。那么socket是什么呢?
socket 是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用,以实现进程在网络中通信。

五、TCP的三次握手
1、首先先了解几个关键名词:
(1)、SNY 同步序列号,TCP建立连接时,将这个位置为1。
(2)、ACK 是TCP报头的控制位之一,是对数据进行确认。确认由目标端发出。比如确认号为X,则表示前X-1个数据确认收到。当ACK=1时,确认号才有效,ACK=0时,确认号无效,这时会要求重传数据,保证数据的完整性。
(3)、FIN 发送端完成发送任务位,当TCP完成数据传输需要断开时,提出断开连接的一方将这位置为1。
(4)、SEQ 用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
2、然后我们来看三次握手的过程:

第一次握手:客户端发送连接请求到服务端,带的报文头部中的信息是: SYN=1以及随机生成初始化序列号seq=x。此时客户端进入SYN-SENT状态,等待服务端的确认。(报文:SYN=1 、seq=x)
第二次握手:服务端收到请求报文后,同意连接,向客户端发送SYN=1,确认标志ACK=1,确认序列号ack=x+1以及随机生成自己的序列号seq=y。此时服务端进入SYN-RCVD状态,询问客户端是否做好准备。
(报文:SYN=1、ACK=1、ack=x+1、seq=y)
第三次握手: 客户端收到服务端确认后,还要向服务端发出确认报文,ACK=1,确认号ack = y+1,以及自己的序列号seq=x+1。此时建立连接,客户端和服务端进入ESTABLISHED状态。
(报文:ACK=1、ack=y+1、seq=x+1)
3、为什么需要3次握手?
简单的来说,假如客户端向服务端进行连接请求,在第一次握手时,由于网络原因这个请求没有及时的到达服务端,而是在某个网络节点中长时间滞留了。等到客户端连接释放了之后,这个请求才到达服务端,此时如果只有2次握手,那么服务端就认为与客户端连接成功了,但是实际上客户端并没有连接。所有如果是3次握手的话,服务端就会因为没有收到客户端的确认报文而没有去建立连接。
六、TCP的四次挥手
1、我们先看下四次挥手的过程

第一次挥手:客户端发出释放信号FIN=1,以及自己的序列号seq=u,此时客户端进入FIN-WAIT-1状态。(报文:FIN=1、seq=u)
第二次挥手:服务端收到客户端请求之后,发送确认标志ACK=1,确认序列号ack=u+1,以及自己的序列号seq=v。此时服务端进入CLOSE-WAIT状态。(报文:ACK=1、ack=u+1、seq=v)
第三次挥手: 客服端收到服务端确认结果之后,进入FIN-WAIT-2状态。此时服务端发送释放信号FIN=1、确认标志ACK=1、确认序列号ack=u+1,自己的序列号seq=w,此时服务端进入LAST-ACK(最后确认状态)。(报文:FIN=1、ACK=1、seq=v、ack=u+1)
第四次挥手:客户端收到回复之后,向服务端发送ACK=1、ack=w+1、seq=u+1,此时客户端进入TIME-WAIT状态。必须经过2MSL(最长报文段寿命)的时间后,客户端没有收到服务端发来的任何数据,证明服务端已正常关闭,进入CLOSED状态。服务端收到客户端的确认后,立刻进入CLOSED状态。(服务端结束TCP连接的时间要比客户端稍微早一些) (报文:ACK=1、ack=w+1、seq=u+1)
2、为什么客户端在第四次挥手的时候,还要等待2MSL计时呢?
因为客户端需要保证最后一次发送的ACK报文到服务器,如果服务器未收到,可以请求客户端重发,这样客户端还有时间重发,重启2MSL计时。TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。
3、为什么ACK报文和FIN报文不能一起发送?
ACK报文是用来应答的,SYN报文是用来同步的。但是在关闭连接时,当服务端接收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,你发的FIN报文我收到了,只有等到服务端所有的数据都发送完了,才能发送FIN报文,因此ACK报文和FIN报文不能一起发送。所以断开连接的时候才需要四次挥手来完成。