目录

  • 1.网络是不可靠的
  • 2.TCP 概念和特点
  • 3.可靠传输机制
    • 1.一问一答的方式
    • 2.流水线传输的方式
      • 1.回退 N 重传
      • 2.选择重传
  • 4.TCP 滑动窗口机制
    • 数据包序号
    • 确认号和累计确认
    • 发送机制
    • 发送窗口
    • 接收窗口
    • 窗口大小
  • 5.TCP的建立和释放
    • 1.建立连接-三次握手
    • 三次握手的必要性
      • 1.三次握手是为了确定双方的收发能力
      • 2.序号同步的确定性
      • 3.历史失效连接请求的乱序问题
      • 4.三次握手中丢包的情况
      • 5.数据传输的开始时机
      • 6.连接关闭 - 四次挥手
      • 7.挥手四次的必要性
      • 8.等待 2MSL 时间的原因
  • 6.TCP协议头
  • 7.概念知识总览

1.网络是不可靠的

计算机网络是不可靠的,存在 丢包、乱序、延时

这是众多 TCP 协议机制的设计出发点,万恶之源,将贯穿全文。

2.TCP 概念和特点

TCP 协议全称 传输控制协议, 是一种 面向连接的、可靠的、面向字节流的 传输层通信协议。

TCP 在 TCP/IP 协议模型 中位于传输层

TCP/IP 模型中各层数据包结构的关系如下图。

TCP 协议的主要特点:

  1. 面向连接,一对一通信。
  2. 可靠交付:保序、不重复、不丢失。
  3. 全双工通信:双方均可收发。
  4. 和上层应用进程的交互方式是 面向字节流的。

TCP 和上层应用进程的交互方式:

  1. 发送方可以发送不同大小的数据块到发送缓存。
  2. 先会对发送缓存内的数据分段,打包成 TCP 数据包再发送。
  3. 在接收一侧,数据包会先进入接收缓存区。
  4. 当一定数量的数据包全部到达,重排、组装,以数据流方式吐给接收方。


虽然 TCP 是面向字节流的,但是 TCP 所处理的数据单元却是面向报文段的, 也就是本文所说的数据包。

将看到,短短 可靠交付 四字背后并不简单。

3.可靠传输机制

若不止考虑 TCP 协议本身的实现,如何设计可靠的网络通信?

首先,由于 丢包的可能性,要实现可靠通信:

  1. 发送方要知道对方接收成功,因此需要接收方回复确认 即 ACK。
  2. 如果丢包发生,发送方需要重传。

一种触发重传的方式是,超时重传 (也有其他触发方法,见后续 TCP 重传机制 )。

网络延时发生时,重传可能会导致重复:

  1. 接收方会丢弃收到的重复数据包,但是仍然回复确认。
  2. 发送方会丢弃收到的重复确认包。
    其次,对于如何发送确认包和重传包,有两种方式。

1.一问一答的方式

也叫做 停止并等待 ARQ 协议, 是指 发送方等到接收方的确认包后,再发下一个数据包 。

类似乒乓方式,具体来说:

  1. 如果时限内收到对方确认,才发送下一个数据包。
  2. 否则,重传当前数据包。

    可以看到这种方式下,发送方大部分时间在等待,效率非常低。

2.流水线传输的方式

叫做 连续 ARQ 协议 , 是指 发送方会连续发送一组数据包,同时等待这些数据包的确认 。
具体来说:

  1. 发送方发送一批数据包。
  2. 同步地接收对方的确认包。

简单来说, 发送方不闲着,一边发送,一边等回复 。

可以看到这种方式相对一问一答的方式,效率要高。

如果发生丢包或延时,需要重传,有两种方式:

1.回退 N 重传

发送方每发送一个数据包,都会发起一个定时器。

一旦一个某个定时器触发,就会重传。

发送指针回退到未拿到确认的数据包处,以实现重传。


可以看到,此方法下, 会重传后面所有的数据包。

2.选择重传

同样,每发送一个数据包,都会发起一个定时器。

不同点仅在于, 只重传未拿到确认的数据包,不回退发送指针。

综合以上,得出的结论是,不考虑 TCP 协议的具体实现的话, 要实现可靠的网络通信,需要依赖确认和重传机制, 并且一个好的办法是采用流水线传输的方式。

而流水线传输方式,正是下一个部分 TCP 协议中的 滑动窗口机制 的引子。

4.TCP 滑动窗口机制

滑动窗口机制是 TCP 协议的精髓所在,它是 TCP 协议设计的基本框架 。

滑动窗口机制就是 流水线传输方式 在 TCP 协议中的细化设计, 发送方一边连续地发送数据包,一边等待接收方的确认。

滑动窗口分为两种:发送窗口接收窗口

由于 TCP 是全双工的, 所以通信的每一端都会同时维护两种窗口 。

数据包序号

可靠传输的基础机制 中, 接收的数据包可能是重复的、乱序的,因此 TCP 会对每一个数据包进行唯一标号, 叫做数据包的序号。

数据包的序号是 TCP 协议头 中的一个 32 比特大小的整数字段。

每次发送一个包,这个序号就会增加一。

TCP 是全双工的,两个通信端各自维护自己的序号。

因为 网络延时不可控, 如果两次连接建立时差很短、或者连接重建后老连接的数据包延迟到达, 会造成序号冲突。

所以,序号并非由固定数字初始化。可以综合时间、随机数来生成等。

确认号和累计确认

在 TCP 中,一个用以确认的回复包,会有确认号。

如果一个数据包同时也是一个确认包,那么它也会有确认号。

一个序号为 SEQ 的数据包,其确认包的确认号会是 SEQ+1

同样,确认号也是 TCP 协议头 中的一个 32 比特大小的整数字段。

可以理解为,接收方已收到序号为 SEQ 的数据包,期待发送方下一次给 SEQ+1 的包。

更广义的理解是, 确认号是接收方期望对方发送的下一个包的序号

下图中,发送方连续发送一组包,如果中间有丢包, 接收方则期待序号最小的丢失的包。当重传成功后, 接收方仍然期待下一个未拿到的数据包:

接收方所期待的是序号最小的没拿到的数据包 。

这种确认号的机制,即可实现累计确认机制:

接收方确认了标号为 SEQ 的数据包, 即代表确认了所有小于 SEQ 的数据包, 此时接收方给的确认号是 SEQ+1

累计确认其实是一种批量确认的机制,以减少确认包的数量。

此外,如果接收方恰好需要发送数据,确认号可以直接标在数据包上,即捎带确认。

一个问题是,如何控制累计确认的时机?

TCP 协议中的 Nagle 算法 给出的办法是 延迟确认

其大概的原理是,未确认的包达到一定量、或者达到一个时间阈值,才回复一次确认。

所以说, 在默认的 TCP 协议中,确认不是立即回复的,而是延迟的 。

不过,接收方的延迟确认不应该过分延迟,否则会造成发送方的重传,浪费网络资源。

可以设置 TCP_NODELAY 选项 来禁用 Nagle 算法。

TCP 的累计确认机制,是累计确认和延迟确认两个策略的综合。

此外,TCP 协议还有另外一种确认机制,叫做 选择确认机制 ,将会后面讲到。

发送机制

已经讲过,TCP 协议默认的 Nagle 算法 采用了延迟确认的方法。

对应的,发送的时机如何确定?

办法是类似的,大概是,未发送的包达到一定量、或者达到一个时间阈值,才发送一次。

TCP 的发送机制,是累计发送和延迟发送两个策略的综合。

同样可以设置 TCP_NODELAY 选项 来关闭延迟发送的行为。

发送窗口

发送窗口的示意图如下,当收到对方的累计确认后,则向右滑动。

注意的是 窗口大小 是有限的(稍后将讨论它的受限情况), 发送方只能发送窗口内的数据包 。

接收窗口

接收窗口的示意图如下,当回复对方确认后,则向右滑动。

仍需注意 窗口大小 是有限的(稍后将讨论它的受限情况), 接收方只能接收窗口内的数据包 。

由于 网络数据包是乱序的 , 所以接收后的数据包会按照序号重新排序,才可以交付给应用程序。

窗口大小

窗口的大小是受限的,也是动态的 。

窗口大小是 TCP 协议头 中的一个 16 比特大小的整数字段。

首先,显然 接收窗口受限于接收缓存区的大小, 发送窗口受限于发送缓存区的大小 。

其次指出, 发送窗口大小也受限于接收窗口大小 。

这其实比较容易理解,发送方是生产者,接收方是消费者, 如果生产速度快而消费速度慢,则会导致接收方来不及接收。

所以,发送方只能发送窗口内的数据包

其实,这就是 流量控制机制 : 由接收方控制的、调节发送方生产速度的机制 , 其具体的实现方式,就是在回复时设置 TCP 协议头 中的窗口大小字段。

窗口的大小也是动态变化的, 因为两端接收和发送能力是动态变化的 :

  1. 接收能力的变化导致窗口大小的变化,即后面所讲的 TCP 流量控制机制
  2. 发送能力的变化导致窗口大小的变化,即后面所讲的 TCP 拥塞控制机制
    可以看到,滑动窗口的大小是一个贯穿式的重要概念。

但是,如果窗口要缩小,窗口的前沿是不可以向前收缩的。

窗口收缩的方法则是,慢慢地,随着已发送的数据包得到确认, 保持窗口前沿不动,前移窗口后沿。

因此, 发送窗口也并不总和接收窗口一样大 。

窗口大小的初始化,是在 连接建立 过程中两端协商确定的, 在后续的传输阶段,它会因主动或被动的原因而动态变化。

5.TCP的建立和释放

1.建立连接-三次握手

首先,TCP 连接建立过程要解决的问题:

  1. 确定双方都可以正常收发 TCP 数据包。
  2. 双方协商一些参数和可选项(例如前面所讲的 选择确认 、窗口大小 等), 尤其是交换初始序号。
  3. 对资源进行分配,比如缓存区、端口号。

下面是 TCP 协议三次握手建立连接的过程示意图,其中

  1. SYN(synchronous) 是同步标志位 ,表示开始传输数据的意思。
  2. ACK(acknowledgement) 是确认标志位,表示是否启用确认机制。
  3. ack(小写)是前面所说的 确认号。
  4. seq 是前面所说的 序号 。

具体过程的描述如下:

  1. 客户端发送一个 TCP 数据包,主动发起连接。

  设置 SYN=1 标志位,表示发起连接,想要传输数据。

  客户端初始化自己的数据包序号 seq=x ,一同发送给对方。

  1. 服务端收到对方的连接请求,回复对方确认包。

  设置回复标志位 ACK=1 ,表示确认。

  根据 确认号的规则, 同时设 ack=x+1 表示期待对方下一次发过来的数据包序号为 x+1。

  因为 TCP 是全双工的,服务端也会设置 SYN=1 , 并初始化自己的数据包序号 seq=y ,捎带回复给客户端。

  此时,服务端可以确定: 客户端可以发送 TCP 数据包,自身可以接收 TCP 数据包 。

  1. 客户端收到对方的确认包,并回复对方确认。

  同样,设置回复标志位 ACK=1,表示确认。

  对方的序号是 y , 回复对方 ack=y+1 表示期待对方下一次发来的数据包序号为 y+1 。

  同时,自身的数据包序号需要自增 seq=x+1 。

  自己发送上一个数据包,对方收到了,并且收到了对方回复。

  所以客户端可以确定: 服务端可以正常收发 TCP 数据包, 自身也可以正常收发 TCP 数据包 。

  1. 服务端收到客户端的确认,三次握手结束

  此时服务端可以进一步确定:

  客户端端可以正常接收 TCP 数据包, 自身也可以正常发送 TCP 数据包 。

三次握手结束后,双方都可以确定对方是可以正常收发 TCP 数据的。

三次握手的必要性

一个经常出现的问题是: 两次握手可以吗?

当然是不可以的,可以分几个方面解释:

1.三次握手是为了确定双方的收发能力

  如果缺少最后一次 ACK 的话,服务端就无法知道客户端是否可以接收 TCP 数据, 也无法知道自己的发送是否成功,就无法做到可靠传输。

2.序号同步的确定性

如果缺少最后一次 ACK 的话,服务端就无法确定对方有无收到自己的初始序号。

前面讲到,数据包的序号是 TCP 滑动窗口机制的基本字段,它如果是不可靠的, 后续的确认机制、重传机制等都无从谈起。

网络是不可靠的,存在丢包,所以连接建立时, 双方都必须确定初始序号交到了对方手中。

三次握手过程,也是可靠地交换初始序号的过程 。

3.历史失效连接请求的乱序问题

网络中,数据传输可能存在延迟、乱序。

如果一个老的失效的连接请求,延迟到达服务端,倘若缺少第三次握手, 服务端会建立一条新连接,直接进入 ESTABLISHED 状态。

客户端收到服务端的回复包时,可以根据序号是否过期判断是否是失效连接。

在三次握手的情况下,客户端就进一步可以发送 RST 标志,终止连接。

如果不是历史失效连接,客户端则发送 ACK 标志,正常建立连接。

4.三次握手中丢包的情况

另一个常见的问题是: 如果第三次 ACK 丢包呢?

无论哪一次通信发生丢包或延迟,都出发 TCP 的 重传机制

简单说,再发一次,如果达到一定次数,则放弃连接。

对于第三次 ACK 丢包的情况,重试一定次数后,服务端会关闭连接,回收资源。

不过,服务端单方面关闭连接,客户端并不知晓,它认为连接已经建立。

如果客户端向服务端发送数据,会被服务端打回 RST 报文, 借此客户端可知道连接失效。

5.数据传输的开始时机

上面的 三次握手图示 中,一个细节是:

  1. 客户端在两次握手之后就进入了 ESTABLISHED 状态。
  2. 服务端则是在三次握手之后才进入 ESTABLISHED 状态。
    其原因在于, 在 第二次握手 后, 客户端已经可以确定双方都可以正常收发数据包 。

所以,客户端可以提前进入 ESTABLISHED 状态,分配端口,开始通信。

因此, 第三次 ACK 是可以捎带客户端的数据一并发送的 。

服务端直到 第三次握手 成功之后,才可以确定双方都正常, 所以它会稍晚进入 ESTABLISHED

6.连接关闭 - 四次挥手

TCP 的连接释放过程,需要注意两个点:

  1. TCP 是全双工的。
  2. 双方都可以主动释放连接。
    释放连接的过程有一个重要的目的:

双方都要确定地知道对方不再发送数据了,连接才正式关闭 。

假设客户端主动关闭,下面是 TCP 协议四次挥手释放连接的过程示意图。

其中 FIN(finish)是结束数据传输的标志位。

具体过程的描述如下:

  1. 客户端发送 FIN 数据包,不再发送数据。

  设置 FIN=1 标志位,表示想要关闭连接,不再发送数据。

  但是,此时服务端还可以继续发送数据 。

  1. 服务端收到 FIN 数据包,回复确认 。

  服务端对于 FIN 包也会进行确认。

  此时服务端明确知道,客户端不再发送数据了 。

  1. 服务端传输完剩余数据 。

  由于 TCP 是全双工的, 连接关闭由客户端主动发起,并不意味着服务端的数据已传输完。

  1. 服务端需要把剩余数据传输完毕。

  此时服务端知道,双方都不再发送数据了。 。

  服务端发送 FIN 数据包,不再发送数据包 。

  同样,设置 FIN=1 标志位,表示服务端不再发送数据。

  1. 客户端收到对方 FIN 包后,回复确认 。

  任何一方结束数据发送,都要确保对方是知道的,就需要对方确认。

  此时客户端知道,双方都不再发送数据了。

  1. 客户端等待 2MSL 时间等待后,四次挥手结束,释放所有资源

再次明确, FIN 标志位的意思是,不再发送数据 。

7.挥手四次的必要性

双方都必须对 FIN 包做确认, 这样对方才可以确定地知道自己不再发送数据。

TCP 连接的建立需要三次握手,是因为, 第二次握手过程服务端将设置 SYNACK 合并为一个数据包发送,所以是三次 。

而对于释放连接的情况, 无法将第二次和第三次合并, 因为中间还要传输数据, 所以是四次。

如果任何一个确认包发生丢包或延迟,主动设置 FIN 的一方会触发重传。

8.等待 2MSL 时间的原因

首先,MSL 是指报文在网络中最大生存时间。

2MSL 就是两倍的 MSL ,也被叫做 TIME_WAIT 时间, 在 linux 中常被设置为 2*60s

2MSL 的值一定需要大于重传超时阈值 。

为何要等待这么长时间呢?

  1. 如果最后一次 ACK 丢包呢?

前面有说过,任何一方的 FIN 包丢失后,如果超时未收到对方确认, 就会触发重传。

  如果客户端在一定时间内未收到服务端的 FIN 包重传,说明对方已经收到 ACK

  否则,如果收到服务端的 FIN 包重传,自然回复 ACK

  一次 ACK 包的发送时间,再算上重传 FIN 的时间,所以叫做 2MSL

  不过,无论如何,2MSL 时间至少要比重传超时阈值长。
2. 防止新老连接数据包混乱
  如果立即释放端口资源,此端口可能被一个新连接立即使用。

  如此的话,假设网络中存在老数据包的延迟,那么老数据包会被新连接接收,造成混乱。

  所以, 等待一定时间,使得网络中潜在的、可能延迟传输的数据包悉数殆尽, 才不会影响到后面的连接。

综合来看,还是因为网络是不可靠的。

6.TCP协议头

7.概念知识总览

计算机网络——TCP 协议原理总结相关推荐

  1. 计算机网络——HTTP协议原理

    摘要 在日常的开发中,很多开发的同学可能很少了解的HTTP协议的底层原理.HTTP协议的底层涉及到请求响应模型,HTTP的工作流程.cookie和session的原理等.本博文主要介绍计算机网络中HT ...

  2. 计算机网络-TCP协议

    目录 1 概述 2 TCP的主要特点 3 TCP的连接 4 可靠传输的工作原理 4.1 停止等待协议 4.1.1 无差错情况 4.1.2 出现差错 4.2 自动重传请求ARQ 4.3 连续 ARQ 协 ...

  3. 计算机网络 TCP协议如何保证可靠传输

    目录 TCP如何保证可靠传输 TCP以段为单位发送数据 重传机制 超时重传 重发超时如何确定 快速重传 SACK 的引入是为了解决什么问题? D-SACK 又是什么东西? ARQ协议 停止等待ARQ协 ...

  4. 计算机网络中TCP连接管理,计算机网络 TCP协议

    TCP:面向连接的运输 TCP协议是面向连接的协议,把连接作为最基本的抽象.每一条TCP连接唯一的被通信两端的两个端点所确定.TCP协议是点对点,而不是点对多点.端点又被称为套接字,TCP协议规定,I ...

  5. 计算机网络——TCP 协议总结

    文章目录 TCP 协议总结 1.主要特点 2.TCP 和 UDP 的区别 3.TCP 头部 4.三次握手--建立连接 5.四次挥手--释放连接 6.流量控制 7.拥塞控制 TCP 协议总结 1.主要特 ...

  6. 计算机网络—TCP协议

    建议将思维导图保存下来观看,或点击这里在线观看

  7. 计算机网络——IP协议基础原理

    摘要 IP协议提供的一种统一的地址格式.它为互联网上的每一个网络和主机分配一个逻辑地址所以IP地址也叫逻辑地址,用来屏蔽物理地址的差异,MAC地址每一个机器都有一个编码.IP地址是32位二进制数据分为 ...

  8. 计算机网络——ARP协议(地址解析)原理

    摘要 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议.主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的 ...

  9. 计算机网络——ARQ协议(自动重传请求)原理

    摘要 自动重传请求(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一.它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输 ...

最新文章

  1. jquery gridly (拖拽插件)
  2. 王高利:awstats
  3. GHOST_XP详细制作过程
  4. 成功解决AttributeError: 'NoneType' object has no attribute '__array_interface__'
  5. 【攻防世界013】elrond32
  6. c++ map的使用方法[转]
  7. office 2003和office 2013同时安装使用的问题
  8. 研发管理(2)---七个工作法则
  9. 无法使用struts2注释_带有注释且没有struts.xml文件的Struts 2 Hello World示例
  10. java秒数格式转换_Java中整数(秒数)转换为时分秒格式(xx:xx:xx)
  11. Map 3D 2012定制和应用程序开发Webcast将于明天(6月23号)进行
  12. OpenCV : 投影变换
  13. url怎么隐藏html后缀,去除url后缀(.html,.jsp等)的有效方法
  14. 网站备案需要买服务器吗,域名备案需要购买服务器吗
  15. forge不能用java打开_我玩我的世界把java更新了以后,就再也进不了加了forge的版本了,启动器,游戏,forge都重...
  16. 2827: 千山鸟飞绝 非旋treap
  17. 在计算机硬盘使用前需要做的工作是,工作电脑的硬盘该如何保养
  18. Java 根据贷款年限对应的不同利率计算月供
  19. 苹果耳机AirPods Max(Pro)的空间音频技术,Unity端开源框架下载
  20. 让word文档中的代码更美观

热门文章

  1. mc启动器需要用的java_《我的世界》为啥需要启动器,而不是直接游戏?专业角度给你分析...
  2. 我的世界电脑版java路径_我的世界启动器Java路径怎么设置?java路径设置攻略
  3. 广义相对论基础【1】狭义相对论中的张量
  4. n行Python代码系列:四行程序实现两个视频同屏播放
  5. 统计信号处理基础 习题解答4-2
  6. 彻底弄懂python3中的回调函数
  7. linux下 远程桌面连接,Unix/Linux下通过远程桌面连接Windows OS
  8. TIFF World File (TFW)格式解析
  9. 应用笔记AN1078一阶数字低通滤波器推导和相位延迟计算
  10. 计划任务-定时关闭、重启软件