大家好 , 这篇文章 , 给大家分享的是 传输层协议中的 UDP 协议 , 以及部分 TCP 协议的知识 . 本篇文章还会给大家讲解网络中非常有名的三次握手四次挥手问题
大家收拾收拾 , 我们准备发车了~
上一篇文章的链接也给大家贴在这里了
文章专栏在此
我们之间提到过 , 传输层有两种协议 : UDP、TCP
传输层中的协议都是操作系统内核中已经包含好了的
我们也介绍过 UDP TCP 的特点
UDP : 无连接、不可靠传输、面向数据报、全双工
TCP : 有连接、可靠传输、面向字节流、全双工
认识协议的细节 , 需要先认识协议的报文格式
特点 : 有连接、可靠传输、面向字节流、全双工
可靠传输 , 是 TCP 最核心的部分 , TCP 内部的很多机制 , 都是在保证可靠传输
这里的可靠传输 , 指的是 : 发了之后 , 对方收没收到 , 我心里清楚 . 而不是说 , 发出去之后 , 对方 100% 就能收到 . 比如 : 极端情况下 , 网线断了 .
那可靠性是如何保证的呢 ?
其中最核心的机制 : 确认应答
举个栗子 :
此处说的 “可靠性” 跟 “安全性” 没有任何关系 .
千万不能把 TCP 这个可靠的通信协议 , 说成 “安全的” 通信协议
安全性指的是 : 数据被截获之后 , 不容易被理解内部的意思 , 以防数据被篡改 . 这是通过加密来做到的
在确认应答的情况下 , 如果收到了 ACK , 就好办 . 那如果没收到呢 ? 还需要通过其他的途径来处理
不是说我们没收到 ACK 就立即放弃 , 我们就需要重新再发一遍数据
网络环境错综复杂 , 尤其是有些时候 , 网络会拥堵 , 就可能导致丢包(数据就丢了)
比如 : 我们打联盟 , 有的时候突然就卡了
- 本地程序卡了 (CPU过载 / 显卡过载 / 硬盘过载) , FPS 降低了 , FPS < 60 就会感觉到明显的卡顿
FPS 代表每秒钟有多少帧 , 数字越大 , 就越流畅
- 网络延时比较大 : 因为网络拥堵导致客户端到服务器之间 , 消耗的时间更长了
可以通过 ping 值来看 , 网络延时比较大 , ping 值就变高了
正常 ping 在 20~30 ms 左右 , 如果 ping > 100ms 就会明显感觉到卡顿
- FPS 和 ping 都不高 , 但是丢包严重 : 如果丢包率达到 5% , 就会有明显卡顿感 . 如果已经达到 10% , 基本就玩不了了
丢包是无差别丢包的 , 任何一个数据报 , 都是有可能丢的
发的普通的报文 , 有可能会丢 ; 发的 ACK 也是有可能会丢的
如果是业务数据丢了
如果是 ACK 丢了
那有没有可能数据丢了一半呢 ?
在超时重传的机制下 , 发一个数据 , 丢包了 . 那么重传数据 , 还是会有可能丢包的
但是站在概率的角度来看 , 就比如假设一次传输数据 , 丢包概率是 10% (已经是一个很大的数字了)
A->B 发一次数据 , 丢包的概率 : 10% .
A->B 连续发两次都丢包的概率 : 10%* 10% = 1%
丢包操作还有一个超时时间 , 超时时间具体是多少 , 在操作系统内核中是可以控制的
第一次传输丢包 , 超时时间是 t1 . 第二次又丢包 , 超时时间是 t2.
一般 t2 > t1 , 这里的等待时间间隔 , 随着时间的推移 , 要越来越大
连续两次都没发过去 , 意味着当前单次发送的丢包概率已经相当大了
连续重传之后丢包的次数越多 , 此时意味着单次发送的丢包概率就更大
很可能是网络上遇到了非常严重的故障 , 短期内恢复不了 . 发送的再频繁 , 也没啥用
如果连续几次重传都不行 , 就只能放弃了
超时重传也不会无限制的重传下去 . 尝试几次之后 , 仍然无法传输过去 , 此时就会放弃尝试 , 然后就只能断开连接尝试重连 . 如果重连也还是连不上 , 就彻底放弃了
我们刚才介绍的两个机制 : “确认应答”、“超时重传” , 这是保证 TCP 可靠性的最核心机制
但是这两个机制 , 面试却很少考 …
TCP 是一个有连接的协议 , 那就一定存在建立连接、断开连接
我们先来看建立连接的过程 : 三次握手
这就相当于男女生恋爱的过程
男生和女生 , 已经关系很好了
男生给女生说 : 我爱你 , 做我对象吧(syn)
女生听到这句话 , 瞬间脸红了(ack) , 然后说我也爱你(syn)
男生:好耶!(ack)
关系就确立好了
三次握手我们认为是一种保证可靠性的机制 , 这个东西相当于 “投石问路”
在正式通信之前 , 先确定好通信链路是否畅通
如果通信链路不畅通 , 后续大概率要丢包
❗ 但是为啥三次握手要握三次呢 ? 四次行不行?
✅ 行,但是没必要,因为效率低
❗ 两次行不行呢 ?
✅ 指定不行的 , 三次握手也是在验证通信双方的发送能力和接收能力是否正常
比如 : 你跟室友连麦打游戏 , 会先试试能不能听到对方说话
我 : 能听到吗 (SYN)
室友 : 能 (SYN + ACK)
我 : ok (ACK)
为了验证通信双方发送能力和接收能力都是正常的
三次握手还能够让通信双方协商一些重要的参数
比如 :
序号要从几开始是需要协商的 , 实际上一次连接中的序号不一定是从 1 开始的
四次挥手就是断开连接的流程
三次挥手是客户端主动发起第一次 . 四次挥手 , 客户端和服务器都可以主动
其中 , 我们还需要关注每个环节涉及到的 Socket API