Loading... ## TCP 协议的主要特点 1. **面向连接型的传输协议** 应用程序在使用 TCP 之前,必须先建立 TCP 传输连接。传输完毕后必须释放。 2. **单播传输** TCP 连接只能进行点对点的数据传输,不支持**多播 (multicast)** 和**广播 (broadcast)** 传输方式。 3. **面向字节流** TCP 不保留报文的边界,以字节流方式传输。 4. **可靠的传输服务** 应答确认,超时重传,滑动窗口协议 5. **支持全双工传输** TCP允许通信双方的应用程序在任何时候都能发送数据,因为TCP连接的两端都设有缓存,用来临时存放双向通信的数据。当然,TCP可以立即发送一个数据段,也可以缓存一段时间以便一次发送更多的数据段(最大的数据段大小取决于MSS)。 6. **支持建立多个并发的 TCP 连接** ## TCP 首部格式 TCP协议首部最小长度是20字节,首部有一个长度可变的选项部分,最大40字节,所以TCP首部长度是20-60字节大小。具体如图: ![TCP 首部.png](https://blog.domineto.top/usr/uploads/2020/04/3192610605.png) 部分字段的解释说明: | 字段 | 大小 | 说明 | | ------------------------------- | :---------- | ------------------------------------------------------------ | | 序号 (Sequence Number) | 4 byte | TCP传输的时候每一个字节都按顺序编号;协议中的序号是本报文段所发送数据第一个字节的序号。序号也用于建立和结束连接时候使用。 | | 确认号 (Acknowledgement Number) | 4 byte | 表示期望收到对方下一个报文段的第一个数据字节的序号。可以用来解决不丢包的问题。 | | 数据偏移 (Offset) | 4 bit | 指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。这个字段实际上是指出 TCP 报文段的首部长度。 | | 保留 (Reserved) | 4 bit | 保留为今后使用,目前应置为 0。 | | 窗口 (window) | 2 byte | 可靠连接和流量控制中所用到的窗口大小。窗口值用于告诉对方:从本报文段首部中的确认号算起,接受方目前允许对方发送的数据量(以字节为单位)。之所以要有这个限制,是因为接受方的数据空间是有限的。 | | 校验和 (Checksum) | 2 byte | 校验和字段检验的范围包括首部和数据两部分。 | | 紧急指针 (Urgent Pointer) | 2 byte | 紧急指针仅在 `URG = 1`时才有意义,它指出本报文段中的紧急数据的字节数。因此,紧急指针指出了紧急数据的末尾在报文段中的位置。 | | 选项 (TCP Option) | 0 ~ 40 byte | 长度可变,最长可达 40 字节。当没有使用 `选项` 时,TCP 的首部长度是 20 字节。 | TCP 首部中含有六个控制位,对建立和结束连接非常关键,说明如下: | 控制位 | 说明 | | ----------------- | ------------------------------------------------------------ | | URG (Urgent) | 紧急字段,可以让该报文不按报文顺序优先被处理。如用户忽然终止传输连接。 | | ACK (Acknowledge) | 确认该字段的值有效。只有当 `ACK=l` 时,确认序号字段才有意义。当 `ACK=0` 时,确认序号没有意义。 | | PSH (Push) | 将数据推向前。当 `PSH=l` 时,请求接收方TCP软件将该报文立即推送给应用程序。 | | RST (Reset) | 连接必须复位。当 `RST=l` 时,表明出现严重差错,必须释放连接,然后重新建立连接。也可用于拒绝连接。 | | SYN (Synchronize) | 建立连接时候的同步标志。当 `SYN=l` ,而 `ACK=0` 时,表明这是一个建立连接请求报文,若对方同意建立该连接,则应在发回的报文中将SYN和ACK标志位同时置1。实质上,就是用 SYN 来代表 Connection Request 和 Connection Accepted ,用 ACK 位来区分这两种情况。 | | FIN (Finish) | 终止连接的标志位。当 `FIN=1` 时,表明数据已经发送完毕,并请求释放连接 | ## TCP 建立连接过程 著名的三次握手: ![TCP三次握手.png](https://blog.domineto.top/usr/uploads/2020/04/1919324224.png) 需要三次握手的原因主要是防止 **已失效的连接请求** 。若使用两次握手,即 A 发送请求,B 返回确认即可建立连接,则可能出现以下情况:A 发送的连接未丢失,而是延滞了。此时 A 放弃了建立连接,但是 B 一段时间后收到了请求,于是返回 ACK 给 A ,此时就错误的建立了连接。 ## TCP 关闭连接过程 ![TCP四次挥手.png](https://blog.domineto.top/usr/uploads/2020/04/1149409882.png) TCP 释放连接包含两个来回。前两次握手代表发送方不再传输数据了。后两次握手代表接收方不再传输数据了,因为TCP是全双工通信,二者是可以同时发送消息和接受消息的。所以图中B的CLOSE-WAIT阶段,仍然可以传输数据。 为什么A在发送确认后还有TIME-WAIT的阶段?有两个理由: 1. A发送的最后一个ACK必须到达B。如果B没有收到该ACK,可能会再次发送FIN+ACK。如果此时A关闭了,B就不可能收到ACK了,也就无法正常关闭。 2. 同三次握手一样,A等待一段时间,可以上网络中本次连接的延滞的请求都发送到位,然后再关闭连接,这样网络里面就不会再剩下本次连接的请求了。 ## TCP 可靠传输 ### 综述 1. **应答确认:** 接收方收到报文会进行确认。 2. **超时重传:** 发送方在一段时间后没有收到确认会进行重传。 3. **数据校验** 4. **数据合理分片和排序** 5. **流量控制:** 当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止丢包。 ### 滑动窗口协议 一个一个传输报文显然效率太低,所以我们可以约定每次发送多个报文,然后采用累积确认的方式。但发送出去的报文可能会丢失,所以我们需要一个缓冲区来维护这些报文,方便重传。 ![滑动窗口.png](https://blog.domineto.top/usr/uploads/2020/04/481414383.png) ## Reference https://www.jianshu.com/p/f35f386ea9c1 最后修改:2020 年 04 月 14 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏