一.TCP/IP协议族的四层模型
应用层(HTTP FTP),传输层(TCP UDP),网络层(IP),链路层。
二.为什么要分层?
因为网络传输的过程中网络是不稳定的。
如图:
其实在我们的网络传输过程中从客户端发送消息的服务端的过程中网络并不是只沿着一条直线可以直接顺利传达到的,它再传输的过程中会经过很多的中间节点,但每一个节点都是有可能是会突然出问题的。如图所示:举一个极端的例子我在传数据的过程中突然停电了或者某一个节点的路由坏了,这时我们的数据就相当于传输失败了,那么这时候我们就需要重新传输数据。但是如果传输的是一个非常大的数据呢?那么我们每次重新传输这个数据的时候必然会造成流量的浪费和速率的降低。
如图:每次传输失败我都需要将数据 ABCDEFGH 从新发送,效率很低!!!
这也就是为什么需要传输层的原因。
三.传输层:TCP协议, UDP协议
传输层主要做的是将你应用层的数据分块编号传输,同时还要确认你的数据到达,如果某一块的数据没有到达那么我只需要再次传输传输失败的内容即可。这样就保证了我只需要传输失败的部分而不是每次都整体重新传输。
如图:我们将原数据拆分为四组数据
当我们传输数据的过程中每次将数据传到服务端的TCP层时,它都会确认并通知客户端对应的编号数据已到达。这时比如3号的传输过程中传输失败了那么客户端是迟迟不能收到服务端回应的,对此我们要做的只是再重新传输失败的3号即可而不是像之前一样整体重新传输。
1.TCP协议所做的事情:保证可靠性和拆块数据
- 客户端TCP层将HTTP层数据拆块。
- 传输数据完成后服务端需要向客户端发送收到信息,如果在规定时间内客户端没有收到服务端发送的信息收到的信息后客户端将重新发送。(超时重传,保证可靠性)。
- 所有数据传输完成后服务端TCP层将拆块的数据组合成原有数据交给HTTP层处理。
2.TCP UDP的区别
- UDP是面向无连接的、不可靠的数据报服务;只需找到目标端口号就可以直接开始发送数据,即发送数据之前不需要建立连接而TCP要经过3次握手创建连接。UDP不需要确认数据是否丢失是否到达,只管传就可以。
- 使用场景: 游戏、视频会议等不需要确认数据有效性且需要快速传输的场景。比如游戏吃鸡,我卡顿两秒后恢复了,我不需要知道这卡顿的两秒发生了什么不需要知道它的数据是什么,我只关心2秒后恢复网络的这最新一帧的画面是什么。
- TCP是面向连接的、可靠的字节流服务。
3.TCP 协议被认为是稳定的协议,因为它有以下特点:(都是为了确保数据不丢失,所有数据都传输成功)
- 面向连接,“三次握手”
- 双向通信( 客户端发送,服务端接收同时告知客户端接收完成)
- 保证数据按序发送,按序到达
- 超时重传
4.TCP的三次握手、四次挥手过程 (连接、断开)
ACK:收到。
SYN:发起一个连接。
FIN:释放一个连接。
4.1 三次握手
简化三步握手的流程就是
- C发给S我要跟你通信。
- S告诉C你可以跟我通信同时我也要跟你通信。
- C告诉S你可以跟我通信,咱们可以开始通信了。
需要三次握手的原因在于S端在第二次握手(发出消息)后并不知道C端是否能接收它发送的消息,如果发送的SYN对方没有收到而直接通信的话会造成只能C到S单方通信(C会收不到S发送的确认消息收到的信息),而TCP连接是需要双端都可以通信的。
4.2 四次挥手
- 第一次挥手:客户端发送一个FIN=1,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。意思是说”我客户端没有数据要发给你了”,但是如果你服务器端还有数据没有发送完成,则不必急着关闭连接,可以继续发送数据。
- 第二次挥手:服务器端收到FIN后,先发送ack=u+1,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息(服务端会等待没有发送的数据发送完毕)。这个时候客户端就进入FIN_WAIT_2 状态,继续等待服务器端的FIN报文。
- 第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=1报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。
- 第四次挥手:客户端收到FIN=1报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=w+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL(2倍最大报文存活时间)后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手。
- 注意:是第四次握手2端才分别关闭的!而不是第三次! S端收到ACK后会关闭连接,同时C端发送ACK后在等待2MSL(2倍最大报文存活时间)后C端连接也会关闭。如果第三次挥手S端直接关闭的话那么如果C端因为网络因素没有收到FIN的话那么客户端会一直等待FIN,这时S端已经关闭了将导致C端永远无法关闭的情况发生。
等待2MSL的原因是S端可能不会收到C端的ACK标志位,那么S端会超时重传重新发送FIN给C端,如果C端不等待2MSL而直接关闭的话会造成C端收不到FIN而S端一直重传FIN导致S端无法关闭的情况发生。(一切都是为了保证四次挥手更加可靠)。
4.3 长连接
- 为什么要长连接?
因为移动网络并不在 Internet 中,而是在运营商的内网,并不具有真正的公网 IP,因此当某个 TCP 连接在一段时间不通信之后,网关会出于网络性能考虑而关闭这条 TCP 连接和公网的连接通道,导致这个TCP端不再能收到外部通信消息,即 TCP 连接被动关闭(比如推送接收不到了,聊天场景中的S端给C端发信息由于连接关闭导致的C端接收不到了)。
- 长连接的实现方式
心跳。即在一定间隔时间内,使用 TCP 连接发送超短无意义消息来让网关不能将自己定义为「空闲连接」,从而防止网关将自己的连接关闭(防止TCP连接通道被被动的关闭)。
四.网络层 IP
- 网络层的作用是在复杂的网络环境中为要发送的数据报找到一个合适的路径进行传输。(也就是从众多节点中选出一条效率最高的路径去传输)
- 网络层不能保证数据报的可靠性传输,可靠性是由网络主机中的传输层(TCP)来进行保证的。也就是说网络层不管传的数据是什么,也不管你传没传送到达,只管一味的传输。(闷头楞传~)
- 图a就是有连接(TCP,有序)的传输:由主机A向主机B传输数据时,提前建立一条连接:主机A->节点1->节点3->主机B。则在由A向B传输多个数据报时,均只能使用这条路线进行传输。
- 图b是无连接(UDP,无序)的传输:当由A向B发送数据报1时,从主机A开始发现由A到节点1的网络比较空闲,就使用这条路径发送,到达节点1时,发现可以使用节点1到节点3的路径,于是就走这条路径,同理再走到主机B;当发送数据报2时,此时发现由A到节点2的网络比较空闲,就使用这条路线发送,之后同理。
五.链路层
- 网络层传输数据需要建立在物理设备的基础上, 链路层就是我们平时接触的网卡和网卡的驱动程序(以太网,WIFI)。
- 上层(比如网络层,传输层等等)不知道也不需要知道数据在物理上是如何传输的。比如数据究竟是用双绞线传输的还是用同轴电缆,到底是有线的网络接口还是无线的网络接口传输,这些细节统统不需要链路层的上层去操心,这样的好处就是比如一会使用有线,一会使用无线,这对于处于网络层的IP实现,或者是传输层的TCP实现来讲,是不需要有任何变化的。