前言
互联网江湖中,UDP如莽夫仗剑疾行,以无连接之刃斩开数据洪流,宁丢包亦不折速度锋芒;TCP似儒雅绅士,借三次握手执礼相待,携重传机制与流量控制,在可靠传输中织就秩序经纬。二者刚柔相济:实时视频里UDP的快意恩仇,网页加载时TCP的君子之约,恰似武林中并存的狂放剑意与绵密掌法,共筑数字世界的通信哲学。
莽夫:UDP协议
想必大家肯定都看过《狂飙》这部电视剧吧,里面一些角色想必大家都印象深刻就比如莽村的李宏伟,而我们现在所要讲述的 UDP协议 它就出自莽村。
面向无连接
现在大家可以先想象一个场景,当我们要发快递给某个人的时候,即使我们知道了收件人的地址,我们还需要先向收件人确认一下基础信息。而 UDP协议 就不一样了它发快递的时候,只要知道了对面的地址就直接发送快递,并不会管别的东西,这就是他身为莽夫的第一层境界。
面向无连接(知道了对面的 ip 后就直接传输数据)
只做数据报文的搬运工
相信大家都听过农夫山泉的一个广告词:我们不生产水,我们只是大自然的搬运工。而 UDP协议 除了莽之外还有点懒,他并不参与数据报文的生成,而是直接拿到本来要发送的数据经过一系列处理之后得到的数据报文进行发送,并且不会增加额外的报文头部。
只做 数据报文(有头和体)的搬运工 (不增加额外的报文头部,头部开销比较小只有8个字节)
不保证数据的有序性和可靠性
关于他的这一点我觉得大家应该能理解,上面两点我们可以看出来这个莽夫并不是一个可靠的人,接下来我们还是以发快递的情景来模仿。
如果我们在网上买一些需要按照顺序组装的东西的话,那么在发快递的时候就会帮你提前按照顺序来编号之类的方便你组装,并且一般会全部都打包给你。但是 UDP 它就是个急性子,它一拿到厂家给你的零件就直接发送了,也不会管你排序什么的,这就不能保证传输过来数据的有序性 了。除此之外,由于它比较急急忙忙的多少都会有点丢三落四,这就引出了它的另一个缺点,它在传输的过程中不保证数据的可靠性,可能会丢包,也就是把你所需要的零件可能路上丢失了。
- 不保证数据包的有序性
- 不保证数据的可靠性(丢包)
没有拥塞控制
说起这个拥塞控制呢,大家在生活中肯定遇到过,当我们在刷视频或者看电视剧的时候,如果网络环境不好的话它就会一卡一卡的,而这个拥塞控制呢就是根据网络环境来控制这个网络传输速度的。
由于 UDP协议 没有拥塞控制,所以它在进行传输的时候,速率是恒定的,并不会因为网络环境的变化而降低速率,这就会导致上面的丢包的出现。干就完了!!!
高效
我们知道它没有拥塞控制之后,那么在我们看电视或者刷视频的时候并不会因为网络环境而影响我们的传输速率,这一点就成就了它高效的一个特点。
UDP 小结
- 面向无连接(知道了对面的 ip 后就直接传输数据)
- 只做 数据报文(有头和体)的搬运工 (不增加额外的报文头部,头部开销比较小只有8个字节)
- 不保证数据包的有序性
- 不保证数据的可靠性(丢包)
- 没有拥塞控制
- 高效(前五点都是高效)
应用场景:直播,视频,游戏,实时性要求高的应用
绅士:TCP协议
现在都是文明社会了,咱就不搞UDP的莽村那一套了,咱们来聊一聊更适合我们社会的 TCP协议,他在进行信息传输的时候并不会像 UDP 一样知道你ip地址直接塞给你就是了,而是会先询问一下你的意见,这就是我们常说的TCP三次握手 ,并且在传输完了信息之后还会非常友好的跟你说:say goodbye,也就是我们常说的TCP四次挥手,接下来我们来学习一下它的绅士礼仪。
头部信息多
在上文中我们聊到 UDP 是数据报文的搬运工,但是 TCP 就比较勤快了,它会往报文的头部添加一些信息用来告诉服务端它想要服务端做的事情,它一般会往头部添加下面的信息。
- Sequence Number (序列号)
- Acknowledgment Number (确认号)
- Window Size (窗口大小,当前网络环境支持传输多少字节的数据)
- 标识符
标识符 | 标识符含义 |
---|---|
URG | 紧急报文 |
ACK | 确认报文 表示当前报文有效 |
PSH | 接收端应该立即将数据传给应用层 |
SYN | 建立连接 |
RST | 需要重连 |
FIN | 关闭连接 |
TCP 三次握手
在我们简单了解完了 TCP 会往头部添加什么之后,接下来我们就来学习一下绅士是如何与人沟通的。当我们客户端向服务端使用 TCP 协议发送信息的时候,通常会通过标识符 来判断你是想要跟我沟通还是不想跟我沟通而这个过程就是我们所说的 TCP三次握手。
首先我们先来了解一下 TCP 三次握手的大致流程,这个场景呢就好比我们去大街上看到心仪的小姐姐,当我们加上小姐姐的vx之后,我们肯定要跟小姐姐进行交流,而交流的经典三部曲就是:
而我们将聊天记录翻译成我们程序员的过程就是:
TCP三次握手过程:
- 客户端发送 SYN 报文,请求建立连接 (客户端进入 SYN-SEND 状态)
- 服务端收到 SYN 报文,回复 SYN + ACK 报文,表示同意建立连接 (服务端进入 SYN-RECEIVED 状态,如果服务端停留在这个状态一段时间会自动关闭)
- 客户端接收到 SYN + ACK 报文,回复 ACK 报文,表示连接建立成功 (客户端和服务端同时进入 ESTABLISHED 状态)
面试官:为什么需要三次握手?两次握手行不行?
当我们了解了什么是TCP三次握手之后,可能就会有同学感到疑惑了,为什么后面还要回复服务端一个好的?如果我只进行两次握手,知道了服务端在的话不就好了。我们都知道东西能简单肯定不复杂,面试官能问出来的问题肯定有坑,接下来我们用一个场景来模拟一下为什么需要三次握手。
首先我们有两个端客户端 A 和服务端 B ,当 A 向 B 第一次发送 SYN 报文请求建立连接时,此时由于网络环境不好导致了 SYN 报文的丢失,这个时候由于客户端的一个机制:当一段时间没有收到回复之后会重新发送 SYN 报文。A 就又向 B 发送了一个 SYN 报文,接下来的过程就完整的走完了 TCP三次握手的流程,客户端 A 关闭。
这时,可能网络环境突然又好起来了,第一次发送的 SYN 报文有可能再次出现再次出现在网络环境中被服务端 B 接收到,当 B 接收到第一次发送的 SYN 报文之后,此时 B 向 A返回 SYN + ACK 报文,并且 B 进入ESTABLISHED 状态,此时由于 A 已经关闭,所以 B 会一直处于这个状态从而进入死锁状态造成资源的浪费。
TCP 四次挥手
跟小姐姐聊天的美好时光总是短暂的,在我们跟小姐姐交流完了之后到点了该打瓦了,这时候就得对小姐姐说再见了,咱们跟小姐姐告别的时候得说一些适当的话,在这里呢我们来学习一下 TCP四次挥手。
同样的我们先来了解一下 TCP四次挥手的大致流程,同样的我们模拟一个跟小姐姐聊天的场景,当我们跟小姐姐聊天的时候突然想打瓦了,这时候我们就得对小姐姐说再见,小姐姐收到后给你发了个好的,可能之前还在打字给你发消息,接着她将刚刚没发完的消息发给你之后,就发了句晚安,这时候你就可以告诉她你收到了并且回了个晚安。
接下来我们用一张过程图给大家展示:
TCP 四次挥手过程:
- 客户端向服务端发送 FIN 报文,请求断开连接 (客户端进入FIN-WAIT-1 状态)
- 服务端收到 FIN 报文,回复 ACK 报文 (服务端进入 CLOSE-WAIT 状态)
- 服务端将未传输完的数据传输完后,向客户端发送 FIN 报文,请求断开连接 (服务端进入 LAST-ACK 状态)
- 客户端收到 FIN 报文,回复 ACK 报文 (客户端进入 TIME-WAIT 状态,一段时间后 CLOSEED )此时服务端进入 CLOSEED 状态
TCP 小结
- 可靠的,面向连接的
- 慢启动,拥塞控制(刚开始会发将包慢慢发送看看网络环境好不好,减少丢包,如果网络环境好就会加快速度)
- 有序的 (这个意思是每个报文上面可以有个类似编号的序列号)