首页 > 代码库 > TCP/ IP 协议

TCP/ IP 协议

  TCP/ IP 协议 通常 放在 一起 来说, 不过 它们 是 两个 不同 的 协议, 所 起 的 作用 也不 一样。 IP 协议是用来查找地址的, 对应着网际互联层, TCP协议是用来规范传输规则的, 对应着传输层。 IP 只 负责 找到 地址, 具体 传输 的 工作 交给 TCP 来 完成, 这就 像 快递 送货 一样, 货单 上 填写 地址 的 规则 以及 怎么 根据 填写 的 内容 找到 客户, 这就 相当于 IP 协议, 而 送货 时 要 先 打电话, 然后 将 货物 送 过去, 最后 客户 签收 时 要 签字 等 就 相当于 TCP 协议。

  TCP在传输之前会进行三次沟通, 一般称为“三次 握手”, 传完数据断开的时候要进行四次沟通, 一般称为“四次挥手”。要 理解 这个 过程 首先 需要 理解 TCP 中的 两个 序号 和 三个 标志 位 的 含义:

  • seq: sequence number 的 缩写, 表示 所 传 数据 的 序号。 TCP 传输 时 每一个 字节 都有 一个 序号, 发送 数据 时会 将 数据 的 第一个 序号 发送 给 对方, 接 收方 会 按序 号 检查 是否 接收 完整 了, 如果 没 接收 完整 就 需要 重新 传送, 这样 就可以 保证 数据 的 完整性。
  • ack: acknoledgement number 的 缩写, 表示 确认 号。 接收 端 用 它来 给 发送 端 反馈 已经 成功 接 收到 的 数据 信息 的, 它的 值 为 希望 接收 的 下一个 数据 包起 始 序号, 也就是 ack 值 所 代表 的 序号 前面 数据 已经 成功 接收 到了。
  • ACK: 确认 位, 只有 ACK= 1 的 时候 ack 才 起作用。 正常 通信 时 ACK 为 1, 第一次 发起 请求 时 因为 没有 需要 确认 接收 的 数据 所以 ACK 为 0。
  • SYN: 同步 位, 用于 在建 立 连接 时 同步 序号。 刚开始 建立 连接 时并 没有 历史 接收 的 数据, 所以 ack 也就 没 办法 设置, 这时 按照 正常 的 机制 就 无法 运行 了, SYN 的 作用 就是 来 解决 这个 问题 的, 当 接收 端接 收到 SYN= 1 的 报文 时 就会 直接 将 ack 设置 为 接 收到 的 seq+ 1 的 值, 注意 这里 的 值 并不是 校验 后 设置 的, 而是 根据 SYN 直接 设置 的, 这样 正常 的 机制 就可以 运行 了, 所以 SYN 叫 同步 位。 需要 注意 的 是, SYN 会在 前 两次 握手 时 都为 1, 这是 因为 通信 的 双方 的 ack 都 需要 设置 一个 初始 值。
  • FIN: 终止 位, 用来 在 数据 传输 完毕 后 释放 连接。

  整个传输过程如图所示。

技术分享

 

  图中上部为三次握手, 下部为四次挥手, 这里 的 四次 挥手 中 画的 是 客户 端 提出 的 终止 连接, 在 实际 传输 过程中 也有 可能 是 服务 端 提出 终止 连接, 它们 的 处理 过程 都是 一样 的。 TCP 的 传输 是 双全 工 模式, 也就是说 传输 的 双方 是 对等 的, 可以 同时 传输 数据, 所以 无论 连接 还是 关闭 都 需要 对 双方 同时 进行。 三次 握 手中 前 两次 可以 保证 服务 端 可以 正确 接收 并 返回 请求, 后 两次 可以 保证 客户 端 可以 正确 接收 并 返回 请求, 而且 在 三次 握手 的 过程中 还 使用 SYN 标志 初始化 了 双方 的 ack 值。 四次 挥手 就是 双方 分别 发送 FIN 标志 来 关闭 连接 并 让 对方 确认。

  三次握手和四次挥手保证 了 连接 的 可靠性, 不过 凡事 有利 就有 弊, 这种 模式 也有 它的 缺点, 首先 是在 传输 效率 上 会 比 较低,另外 三次 握手 的 过程中 客户 端 需要 发送 两次 数据 才可 以 建立 连接, 这种 特性 可能 被 一些 别有用心 的 人 利用, 比如, 发出 第一次 握手( 并 接到 第二次 握手) 后 就不 回应 第三次 握手 了, 这时 服务 端 会 以为 是 第二次 握手 的 数据 在 传输 过程中 丢失 了, 然后 重新 发送 第二次 握手, 默认 情况下 会 一直 发送 五次, 如果 发送 五次 后 还 收 不到 第三次 握手 则 会 丢弃 请求, 如果 是个 别 这种 请求 当然 也没 什么 关系, 可 凡事 就 怕 一个 多 字, 当 有大 量 这种 请求 时 就 麻烦 了, 这时 服务器 就会 浪费 大量 的 资源 甚至 可能 导致 无法 处理 正常 的 请求, 这就 是 DDOS 攻击 中的 SYN Flood 攻击, 对于 这种 攻击 的 一种 应对 方法 是 设置 第二次 请求 的 重发 次数( tcp_ synack_ retries), 不过 重发 的 次数 太小 也可能 导致 正常 的 请求 中 因为 网络 没有 收到 第二次 握手 而 连接 失败 的 情况, 具体 设置 为多 少 合适, 还需 要 根据 实际情况 判断, 当然 如果 资金充足 也可以 使用 硬 防。

  用于 传输 层 的 协议 除了 TCP 还有 UDP, 它们 的 区别 主要 是 TCP 是有 连接 的, UDP 是 没有 连接 的, 也就是说 TCP 协议 是在 沟通 好 后 才会 传 数据, 而 UDP 协议 是 拿到 地址 后 直 就 传 了, 这样 产生 的 结果 就是 TCP 协议 传输 的 数据 更 可靠, 而 UDP 传输 的 速度 更快。 TCP 就 像是 打电话, 需要 先 拨通 对方 号码 才能 通信, 而 UDP 就 像是 使用 对讲机, 拿起 来就 可以 直接 讲话。 通常 视频 传输、 语音 传输 等 对 完整性 要求 不高 而对 传输 速度 要求 高 并且 数据 量大 的 通信 使用 UDP 比较 多, 而 邮件、 网页 等 一般 使用 TCP 协议。

  HTTP 协议 的 底层 传输 默认 使 用的 是 可靠 的 TCP 协议, 不过 它对 互 联网 的 高速 发展 带来 了 很大 的 制约, Google 制定 了 一套基于 UDP 的 QUIC( Quick UDP Internet Connection) 协议, 这种 协议 基于 TCP 和 UDP 之间, 不过 现在 还没有 广泛 使用。

  TCP/ IP 协议 只是 一套 规则, 并不能 具体 工作, 就 像是 程序 中的 接口 一样, 而 Socket 是 TCP/ IP 协议 的 一个 具体 的 实现。

来自:韩路彪 著. 看透Spring MVC:源代码分析与实践 (Web开发技术丛书)


TCP/ IP 协议