UDP & TCP介绍
UDP
报文格式
对于网络协议, 本质上就是就是定义了一个数据的组织格式, 因此我们先来看一下UDP的报文格式, 随后根据其报文格式去了解它的具体功能.
下面是 UDP 协议一个报文的基本格式
下面我们就来简单介绍一下其中的报文格式
报文内容介绍
端口号
首先 UDP 作为一个传输层的协议, 那么就会有端口号信息, 从报文格式中我们也可以看出, 刚开始就直接提供了源端口和目的端口的信息, 这个并没有什么好介绍的, 我们直接看下一个内容
报文长度
报文长度, 顾名思义就是去描述 UDP 的报文多长的. 那既然要描述一个东西有多长, 自然它的单位就是非常重要的, 比如我描述一条路有多长, 那此时如果我说 1 肯定是不行的, 我肯定要说例如 1m, 1km这样的.
那么 UDP 这里的报文长度, 则是以字节为单位的, 那么两个字节, 也就是 16bit, 也就是能描述 2 ^ 16 - 1 个字节, 即 65535 个字节. 那此时有人就要说了, 才这么一丁点, 一次传输才能传 64KB.
这也是 UDP 的局限性, 只能用于传输比较小的数据, 虽然对于当初计算机刚刚发展起来的时候, 64KB 已经非常够用了, 但是在当今这个时代, 肯定是不太够的.
那此时有人就要问了: 那假如我想要使用 UDP 来传输一个比较大的数据, 那么能不能实现呢?
实际上是可以的, 但是成本会比较高. 例如我们可以将数据进行拆分, 分批次发送, 但是如果要拆分数据发送, 那么我们势必就要考虑一些问题, 例如:
- 数据的先后顺序问题: 网络中是存在后发先置的问题的, 也就是说后面发的数据反而可能先到了. 那么此时就会有数据先后顺序问题
- 数据如何拆分和拼接: 既然要拆分, 我们就要规定拆分的规则, 同时规定对应的合并规则
- 中间的某些数据丢了: 网络传输过程中, 是可能会发生丢包的情况的, 那么此时如果中间的数据丢了怎么办?
可以看到, 此时要考虑这些问题, 还是比较麻烦的, 因此这里实际上有一个更简单的方式去传输大的数据, 就是直接使用 TCP 协议传输. 那为什么 TCP 可以传输? 它不会有上面的这些问题吗? 这些问题就留到我们学习 TCP 的过程中解答.
校验和
校验和, 从它的名字里面也可以看出, 它是用于校验的, 那它是用于校验什么的? 怎么校验的?
在网络传输的过程中, 难免会涉及到一些外界条件的影响, 那此时可能就会导致我们传输的数据发生一些损坏, 使其不完整或者是直接就没了.
其中数据没了, 我们直接都收不到自然就不用校验, 我们校验的主要是数据是否损坏这个问题. 那如何去检验这个数据是否完整呢. 此时就是需要靠这个校验和来实现
校验和会采取一些算法, 使其按照相同数据计算出的校验和一定是相同的. 那么假如我接收到数据后, 发现我算一下数据, 校验和不一样了, 此时就认为数据发生了损坏, 不会使用了.
那此时自然就有一个问题: 如果我的校验和在不同数据上算出的长一样怎么办?
这个实际上主要就是涉及到校验和的算法选择问题, 如果选择的算法合适, 那么此时发生这样事件的概率就是比较低的. 其中 UDP 采取的算法比较简单, 就是把数据里面的每一个字节进行累加, 加到溢出也不管, 加到最后就是我们的校验和, 很明显这个算法并不是非常的靠谱, 冲突的概率还是比较高的.
那此时可能有人要问了: 那如果我的校验和坏了呢? 我怎么检验呢?
一般来说, 如果你校验和都坏了, 此时证明你的数据就是损失过的, 那么此时自然对不上才是最好的, 因此这个并不会引发什么问题.
载荷
载荷实际上就是用于装载数据的部分, 这部分其实没有什么可以详细介绍的. 我们主要需要知道的是, UDP 是面向数据报来传输数据的, 也就是说 UDP 在你传输数据前, 要求你要先把数据进行打包, 然后才能传输.
TCP
了解了 UDP 之后, 我们发现 UDP 在某些方面似乎并不是非常的好用, 因此在日常使用中, 我通常都会采用 TCP 来进行传输. 而对于 TCP 协议, 有一个非常重要的特点, 即可靠传输. 可靠传输可以说是 TCP 的初心, 下面我们了解 TCP 机制的过程中, 也可以发现 TCP 实际上就是围绕着可靠传输来设计的.
报文格式
首先我们依旧是来看 TCP 的报文格式, 其基本报文格式如下
当然, 这个报文格式可能不是最新的, 但是基本上核心的部分都涉及到了, 如果要参考最新的标准, 那么推荐阅读 RFC 标准文档里对于 TCP 的描述, RFC 标准文档就是定制了一系列的网络等方面的标准, 如果想要获取最准确的信息, 那么一定是推荐去阅读这个文档的. 文档链接: Transmission Control Protocol (TCP)
接下来我们先初步了解TCP中一些比较容易理解的部分, 剩余的部分我们会在介绍 TCP 机制的过程中进行介绍
初步了解
-
源/目的端口号: 传输层协议存储的端口信息
-
四位首部长度:
用于描述下面的这个选项位置是否需要
此时我们可以看出, TCP 的报头是可变长的
-
保留位: 保留下来的可以用于拓展的位置
-
校验和:
用于校验数据完整性的, TCP采用的是反码求和算法, 算法原理如下:
-
将 TCP 的报文划分为一个一个的 16 位二进制
-
把这些二进制进行相加, 如果进位放到下一次计算中一起加
-
对二进制相加的结果进行取反, 此时得到校验和
然后检验过程如下:
-
把数据按照相同的方式进行二进制相加
-
把加出来的总和和校验和进行相加, 此时相当于原码和反码相加, 正常来说会得到全 1 的二进制, 如果得到全 1, 证明数据没有损坏
-
剩余的部分, 我们会在了解 TCP 机制的过程中了解到具体功能, 这里就不介绍了.
TCP机制
确认应答
序号和确认序号这两个位置, 实际上是为 TCP 的确认应答机制而设计的.
确认应答指的就是, TCP 的消息接收方, 会在收到消息后, 返回一个 ACK 的报文, 告诉消息的发送方已经收到数据了. 此时这个 ACK 报文主要由这个 ACK 标志位表示. 如果 ACK 位是 1, 那么就证明这是一个 ACK 数据报, 而如果是 0, 则证明不是.
那此时就可能有人要问了: 那这两个序号又和确认应答有什么关系呢?
实际上, 由于网络通信过于复杂, 有时候会出现一些 ACK 和对应发送的信息对不上的情况发生, 举一个例子来看.
假如张三和李四分别是发送端和接收端, 发生了这样的对话
那么很明显, 此时的这个好
对应的就是要不要一起吃饭
, 而这个滚
则是对应你可不可以转我一百万
的. 但是由于网络的复杂性, 此时可能又会产生下面的这个情况
可以看到, 此时李四后面回的消息, 反而先到达了, 此时就可能会产生歧义, 张三此时就会想: 这李四居然不想和我吃饭, 而是想转我一百万, 真是我的好兄弟啊. 但是实际上并不是这样的
此时的这种情况就被称作为是"后发先置", 这种情况在网络中是非常常见的, 因为在网络的传输是有非