乐趣区

那些年被我们误解的TCP

引言

最近在结合“慕课网”的实战课程《剑指 Java 面试 -Offer直通车》复习基础知识,在复习计算机网络时,发现原来我在书上学的 TCP 相关知识是不准确的,不符合面试要求。

这是我学习计算机网络时使用的课本,让我们一起来见识见识真正的TCP

学习

简介

TCP:全称 Transmission Control Protocol,传输控制协议。TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。

我们每天都在用的 HTTPHTTPS 都是基于运输层的 TCP 协议。

TCP数据包格式

每个 TCP 报文内都有序号和确认号,结合重传机制保障数据传输的可靠性。

TCP报文中的下列三种表示十分重要。

ACK:确认序号标志
SYN:同步序号,用于建立连接过程
FINfinish 标志,用于释放连接

三次握手

TCP连接中最著名的要属 三次握手 了!

详解

第一次握手:建立连接时,客户端发送 SYN (seq = x) 包到服务器,同时进入 SYN_SEND 状态,等待服务器确认。

第二次握手:服务器收到 SYN 包,必须确认客户的 SYN (ack = x + 1),同时自己也发送一个SYN (seq = y) 包,即 SYN + ACK 包,此时服务器进入 SYN_RECV 状态。

第三次握手:客户端收到服务器的 SYN + ACK 包,向服务器发送确认包 ACK (ack = y + 1),此包发送完毕,客户端和服务器进入ESTABLISHED 状态,完成三次握手。

为什么需要三次握手才能建立起连接?

非常有深度的问题,非认真思考而不可达。

这是《计算机网络》一书中对此的解释。

满满的两页,一句说到核心的都没有。

TCP三次握手的核心是交换 ClientServer初始的Sequence Number

假设

我们假设 TCP 连接中没有三次握手。我们再假设通信过程中已经建立好了 ClientServer的全双工通信通道。

如果 ClientServer发送数据包。该数据包编号是18888,长度是100

如果是正确收到,根据 TCP 的机制,应该回复ACKack = 18988

如果是这个数据包时第一个数据包,这样是合理的,回复 18988,意味着当前的18988 之前的数据包都已经收到了,下一个期待的数据编号是18988

假设 ClientServer同时发送了两个数据包,1878818888,而18788 因为网络的问题,传丢了。那服务器端再回复 ACK 就不合理了。

所以,在 TCP 连接中通信的双方,都需要知道对方所开始发送数据的初始的 Sequence Number。而为了完成这个任务,才有了TCP 的三次握手。

三次握手

  1. 客户端发送它的 Sequence Number 初始值。
  2. 服务端确认收到。
  3. 服务端发送它的 Sequence Number 初始值。
  4. 客户端确认收到。

2、3两步可以进行合并,即服务端发一个 TCP 数据包就可以完成确认和发送自己的 Sequence Number 两项任务,所以就是三次握手。

总结

写书不易,出错时难免的,每位作者也都应该收到尊重。

但是毕竟作为教授万千学子的教科书,请求学校选择课本时请慎重。

退出移动版