1.协议特点
TCP 协议是在不可靠的 IP 协议上实现可靠数据传输的协议,主要具有以下特点:
- 面向连接的传输层协议。
- 进程对进程的通信协议。
- 提供可靠交付服务,保证数据无差错、不丢失、不重复且有序。
- 提供全双工通信。
-
2.报文段结构
源端口和目的端口:发送进程和接收进程的端口号。
- 序号:当前报文段所发送的字节流的第一个字节的序号。
- 确认号:期望收到的下一个报文段的、数据部分的、第一个字节的序号。若确认号为 N,则表明序号 N-1 为止的所有数据都以正确接收。
- 数据偏移:首部长度,单位为 4B,所以 TCP 首部最大长度为 60B。
- 保留:当前不做使用,应置 0。
- 紧急位URG:当 URG 置 1 时,紧急指针字段有效,表示此报文段有紧急数据,系统应尽快传送。
- 确认位ACK:当 ACK 置 1 时,确认号字段有效。
- 推送位PSH:当 PSH 置 1 时,表示当前报文段应尽快交付给接收应用进程,而不再等到整个缓存都填满之后再向上交付。
- 复位位RST:当 RST 置 1 时,表示 TCP 连接中出现严重差错,必须释放连接,然后再重建运输连接。
- 同步位SYN:当 RST 置 1 时,表示这是一个连接请求或者连接接受报文。
- 终止位FIN:当 RST 置 1 时,表示此报文段的发送方的数据已发送完毕,并要求释放运输连接。
- 窗口:允许发送方发送的数据量。
- 校验和:校验整个报文段。
- 紧急指针:紧急数据在报文段数据的最前面,紧急指针指出紧急数据有多少字节。
3.建立连接
TCP 连接的端口是套接字(Socket),每条 TCP 连接被通信的两个套接字确定。
- 第一步:客户机向服务器发送 TCP 连接请求报文段。这个特殊报文段的 SYN 被置位 1,同时选择一个初始化序号
。TCP 协议规定,SYN 报文段不能携带数据,但要消耗掉一个序号。发送连接请求报文段之后,客户机进程进入SYN-SENT(同步已发送)状态。
- 第二步:服务器收到连接请求报文段后,如果同意建立连接,则向客户机发回确认,并为该 TCP 连接分配缓存。连接确认报文段中,SYN 位和 ACK 位都置为 1,确认号
,同时也为自己选择一个初始序号
。发送连接确认报文段后,服务器进入SYN-RCVD(同步收到)状态。
第三步:客户端收到服务器的连接确认报文段后,还要向服务器给出确认,并为该 TCP 连接分配缓存。确认报文段的 ACK 置 1,确认号
,序号
。该报文段可以携带数据,若不携带数据则不消耗序号。此后客户端就进入ESTABLISHED(已建立连接)状态。
4.释放连接
参与 TCP 连接的两个进程中的任何一方都能终止该连接。
第一步:客户机打算关闭连接时,就像服务器发送连接释放报文段,并停止发送数据。该报文段的终止位 FIN 被置为 1,序号
(等于前面已传送过的字节流的最后一个字节的序号加 1)。同样,FIN 置 1 的报文段不能携带数据,但也要消耗掉一个序号,然后客户机进入 FIN-WAIT-1(终止等待 1)状态。
- 第二步:服务器收到连接释放报文段后即发出确认,确认号
,序号
(等于前面已传送过的字节流的最后一个字节的序号加 1),然后服务器进入CLOSE-WAIT(关闭等待)状态。此时,客户机到服务器方向的连接的释放完毕,但服务器到客户机方向的连接任然存在,服务器依然可以向客户机发送数据,且客户机也会接收。
- 第三步:若服务器已经没有数据要向客户机发送,就向客户机发送连接释放报文段。该报文段终止位 FIN 置 1,确认位 ACK 置 1,序号
(
就表示服务器向客户机发送的字节流长度),确认号依旧为
,然后服务器进入LAST-ACK(最后确认)状态。
- 第四步:客户机收到服务器的连接释放报文段后即发出确认,该报文段确认位 ACK 置 1,确认号
,序号
。特别注意,发送完该报文段之后,客户机必须等待 2MSL(最长报文段寿命)时间后,才能关闭连接。
5.可靠传输机制
- 校验机制:在计算校验和时,首先要在 TCP 报文段之前添加 12B 伪首部,它包括源 IP 地址、目的 IP 地址、8 位保留字节、8 位传输层协议号(TCP是 6,UDP是 16)和 16 位报文段长度。如果 TCP 报文段的数据部分不是偶数字节,还要在末尾添加一个不发送的全 0 字节,再做校验和计算。
- 序号:TCP 协议将字节建立在字节流上,而不是报文段上。
- 确认:TCP 默认使用累计确认机制,只确认数据流中至第一个丢失字节为止的字节。
重传
- 超时重传:TCP 每发送一个报文段,就对这个报文段设置一次计时器。计时器设置的重传时间到期但还未收到确认时,就要重传这一报文段。TCP 采用自适应算法设置计时器重传时间,这是一个基于报文段往返时延的加权平均往返时间,会随新测量往返实验样本值的变化而变化。
- 冗余ACK:TCP规定,当接收方收到比期望序号大的失序报文段是,就发送一个冗余ACK,指明下一个期待字节的序号。当发送方收到对同一报文段的 3 个冗余 ACK 时,就认为跟踪这个被确认报文段之后的报文段丢失。
6.流量控制
接收窗口(rwnd):接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,即调整 TCP 报文段首部中的“窗口”字段值。
拥塞窗口(cwnd):发送方根据其对当前网络拥塞成都的估计而确定的窗口值,其大小与网络的带宽和时延密切相关。
下面是接收窗口流量控制的简单模型:7.拥塞控制
拥塞控制是指防止过多的数据注入网络,保证网络中的路由器或链路不至过载。
拥塞控制与流量控制的区别:拥塞控制是一个全局性的过程,是对整个网络的宏观调控。流量控制始端对端的控制,主要是协调协议双发收发数据的速率。7.1 慢开始和拥塞避免
7.1.1 慢开始算法
慢开始是指 TCP 开始发送报文段时先设置拥塞窗口为 1,使得发送窗口开始时只发送一个报文段,以此来试探网络的拥塞状况,然后每进过一个传输轮次(即往返时延)拥塞窗口就加倍,直至规定的慢开始门限 ssthresd,再该用拥塞避免算法。7.1.2 拥塞避免算法
每经过一个传输轮次就把发送方拥塞窗口加 1,使拥塞窗口缓慢增长。
根据拥塞窗口的大小不同,执行不同的算法:
当
时,使用慢开始算法。
- 当
时,使用拥塞避免算法。
- 当
时,通常使用拥塞避免算法,也可以使用慢开始算法。
7.1.3 网络拥塞处理
无论是在慢开始阶段还是拥塞避免阶段,只要发送方判断网络出现拥塞(确认超时),就要吧慢开始门限 ssthresh 设置为出现拥塞时的发送方的拥塞窗口值的一半(但不能小于2)。然后将拥塞窗口重新置为 1,再执行慢开始算法。7.2 快重传和快恢复
7.2.1 快重传
当发送方连续收到三个重复的 ACK 报文段时,直接重传对方尚未收到的报文段,而不必等待那个报文段设置的重传计时器超时。
7.2.2 快恢复
当发送方连续收到三个冗余 ACK 时,就把慢开始门限 ssthresh 设置为此时发送方拥塞窗口值的一半,然后执行拥塞避免算法。
快恢复认为:发送方收到冗余 ACK 时网络可能没有发生严重拥塞,否则就不会有几个连续 ACK 到达接收方,将拥塞窗口渐变是为了预防网络拥塞的发送。
