TCP 传输控制协议——详细

目录

 1 TCP 

1.1 TCP 最主要的特点

1.2 TCP 的连接

TCP 连接,IP 地址,套接字

1.3 可靠传输的工作原理

1.3.1 停止等待协议

(1)无差错情况

(2)出现差错

(3)确认丢失和确认迟到

(4)信道利用率

停止等待协议要点

1.3.2 连续 ARQ 协议

1.4 TCP 报文段的首部格式

1.5 TCP 可靠传输的实现

1.5.1 以字节为单位的滑动窗口

1.5.2 超时重传时间的选择

1.5.3 选择确认 SACK

1.6 TCP 的流量控制

1.6.1 利用滑动窗口实现流量控制

1.7 TCP 的拥塞控制

1.7.1 TCP 的拥塞控制方法

1.8 TCP 的运输连接管理

1.8.1 TCP 的连接建立——三次握手

1.8.2 TCP 的连接释放——四次挥手

1.9 TCP 的有限状态机


 1 TCP 

1.1 TCP 最主要的特点

1.TCP 是面向连接的运输层协议。

2.每一条 TCP 连接只能有两个端点 (endpoint),每一条 TCP 连接只能是点对点的(一对一)。

3.TCP 提供可靠交付的服务。

4.TCP 提供全双工通信。

5.面向字节流

        ·TCP 中的“流”(stream) 指的是流入或流出进程的字节序列

        ·面向字节流:虽然应用程序和 TCP 的交互是一次一个数据块,但 TCP 把应用程序交下来的数据看成仅仅是一连串无结构的字节流

TCP 面向流的概念:

        ·TCP 不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系。

        ·但接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样

1.2 TCP 的连接

·TCP 把连接作为最基本的抽象

套接字 (socket):

TCP 连接,IP 地址,套接字

·TCP 连接就是由协议软件所提供的一种抽象

·TCP 连接的端点是抽象的套接字,即(IP 地址:端口号)。

·同一个 IP 地址可以有多个不同的 TCP 连接。

·同一个端口号也可以出现在多个不同的 TCP 连接中。

Socket 有多种不同的意思:

·应用编程接口  API  称为 socket API, 简称为 socket。

·socket API 中使用的一个函数名也叫作 socket。

·调用 socket 函数的端点称为 socket。

·调用 socket 函数时其返回值称为 socket 描述符,可简称为 socket。

·在操作系统内核中连网协议的 Berkeley 实现,称为 socket 实现。

1.3 可靠传输的工作原理

IP 网络提供的是不可靠的传输。

·在理想传输条件下,不需要采取任何措施就能够实现可靠传输。

·但实际网络都不具备理想传输条件。必须使用一些可靠传输协议,在不可靠的传输信道实现可靠传输。->停止等待协议、连续 ARQ 协议

1.3.1 停止等待协议

·每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。

·全双工通信的双方既是发送方也是接收方。

·假设仅考虑 A 发送数据,而 B 接收数据并发送确认。因此 A 叫做发送方,而 B 叫做接收方。

发送方

        1.发送数据              

        2.计时    

        3.确认发送下一包  :未超时              

        4.重传数据:超时      

        5.丢弃重复的确认信息

接收方

        1.接收数据

        2.检错                  

        3.发送确认信息(无错)

        4.丢弃数据(数据位错误,重复数据)

(1)无差错情况

(2)出现差错

两种情况:

        ·B 接收 M1 时检测出了差错,就丢弃 M1,其他什么也不做(不通知 A 收到有差错的分组)。

        ·M1 在传输过程中丢失了,这时 B 当然什么都不知道,也什么都不做。

·在这两种情况下,B 都不会发送任何信息

问题:A 如何知道 B 是否正确收到了 M1 呢?

解决方法超时重传

        1.A 为每一个已发送的分组设置一个超时计时器。

        2.A 只要在超时计时器到期之前收到了相应的确认,就撤销该超时计时器,继续发送下一个分组 M2 。

        3.若 A 在超时计时器规定时间内没有收到 B 的确认,就认为分组错误或丢失,就重发该分组。

(3)确认丢失和确认迟到

确认丢失

        1.若 B 所发送的对 M1 的确认丢失了,那么 A 在设定的超时重传时间内将不会收到确认,因此 A 在超时计时器到期后重传 M1。

        2.假定 B 正确收到了 A 重传的分组 M1。这时 B 应采取两个行动:

                (1) 丢弃这个重复的分组 M1,不向上层交付。

                (2) 向 A 发送确认

确认迟到

        1.B 对分组 M1 的确认迟到了,因此 A 在超时计时器到期后重传 M1。

        2.B 会收到重复的 M1,丢弃重复的 M1,并重传确认分组。

        3.A 会收到重复的确认。对重复的确认的处理:丢弃

(4)信道利用率

优点:简单。缺点:信道利用率太低。

停止等待协议要点

·停止等待。发送方每次只发送一个分组。在收到确认后再发送下一个分组。

·暂存:在发送完一个分组后,发送方必须暂存已发送的分组的副本,以备重发。

·编号。对发送的每个分组和确认都进行编号。

·超时重传。发送方为发送的每个分组设置一个超时计时器。若超时计时器超时位收到确认,发送方会自动超时重传分组。  

·超时计时器的重传时间应当比数据在分组传输的平均往返时间更长一些,防止不必要的重传。

·简单,但信道利用率太低

1.3.2 连续 ARQ 协议

·通常 A 最终总是可以收到对所有发出的分组的确认。如果 A 不断重传分组但总是收不到确认,就说明通信线路太差,不能进行通信。

·使用上述的确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信。

·像上述的这种可靠传输协议常称为自动重传请求 ARQ  (Automatic Repeat reQuest)。意思是重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组。

发送窗口:发送方维持一个发送窗口,位于发送窗口内的分组都可被连续发送出去,而不需要等待对方的确认。

发送窗口滑动:发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置

累积确认:接收方对按序到达最后一个分组发送确认,表示:到这个分组为止的所有分组都已正确收到了。

        -优点:容易实现,即使确认丢失也不必重传。

        -缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息。(例如不按序到达的)

连续 ARQ 协议采用 Go-back-N(回退N)。

Go-back-N(回退N):表示需要再退回重传已发送过的 N 个分组。 当通信线路质量不好时,连续 ARQ 协议会带来负面的影响。

1.4 TCP 报文段的首部格式

·TCP 虽然是面向字节流的,但 TCP 传送的数据单元却是报文段。

·一个 TCP 报文段分为首部和数据两部分,而 TCP 的全部功能都体现在它首部中各字段的作用。

·TCP 报文段首部的前 20 个字节是固定的,后面有 4n 字节是根据需要而增加的选项 (n 是整数)。因此 TCP 首部的最小长度是 20 字节

·源端口目的端口各占 2 字节。端口是运输层与应用层的服务接口。 运输层的复用和分用功能通过端口实现。

·序号:占 4 字节。TCP 连接中传送的数据流中的每一个字节都有一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。

·确认号:占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号。

        -若确认号 = N,则表明:到序号 N – 1 为止的所有数据都已正确收到。

·数据偏移(即首部长度):占 4 位,指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。单位是 32 位字(以 4 字节为计算单位)。 

·保留:占 6 位,保留为今后使用,但目前应置为 0。

·紧急 URG:控制位。当 URG = 1 时,表明紧急指针字段有效,告诉系统此报文段中有紧急数据,应尽快传送 (相当于高优先级的数据)。

·确认 ACK:控制位。只有当 ACK =1 时,确认号字段才有效。当 ACK =0 时,确认号无效。

·推送 PSH (PuSH) :控制位。接收 TCP 收到 PSH = 1 的报文段后,就尽快(即“推送”向前)交付接收应用进程,而不再等到整个缓存都填满后再交付。

·复位 RST (ReSeT) :控制位。当 RST=1 时,表明 TCP 连接中出现严重差错(如主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。

·同步 SYN (SYNchronization) :控制位。 同步 SYN = 1 表示这是一个连接请求或连接接受报文。

        当 SYN = 1,ACK = 0 时,表明这是一个连接请求报文段。

        当 SYN = 1,ACK = 1 时,表明这是一个连接接受报文段。

·终止 FIN (FINish) :控制位。用来释放一个连接。 FIN=1 表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。

·窗口:占 2 字节。 窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(以字节为单位)。

        -窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化

·检验和:占 2 字节。检验和字段检验的范围包括首部和数据这两部分。 在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部

        在计算检验和时,临时把 12 字节的“伪首部”和 TCP 报文段连接在一起。伪首部仅仅是为了计算检验和。

·紧急指针:占 2 字节。在 URG = 1时,指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据),指出了紧急数据的末尾在报文段中的位置。

·选项:长度可变,最长可达 40 字节。

        —— 长度可变。TCP 最初只规定了一种选项,即最大报文段长度 MSS。MSS 告诉对方 TCP:“我的缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节。”

·填充:使整个 TCP 首部长度是 4 字节的整数倍。

MSS (Maximum Segment Size) 是 TCP 报文段中的数据字段的最大长度。 数据字段加上 TCP 首部才等于整个的 TCP 报文段。 所以,MSS是“TCP 报文段长度减去 TCP 首部长度”。

选项(2):最大报文段长度 MSS。最大报文段长度 MSS  (Maximum Segment Size) 是每个 TCP 报文段中的数据字段的最大长度。

与接收窗口值没有关系。

选项(3):窗口扩大。TCP 窗口字段长度= 16 位,最大窗口大小 = 64 K 字节。 对于传播时延和带宽都很大的网络,为获得高吞吐率较,需要更大的窗口。

·窗口扩大选项:占 3 字节,其中一个字节表示移位值 S

·新的窗口值位数从 16 增大到 (16 + S),相当于把窗口值向左移动 S 位

·移位值允许使用的最大值是 14,窗口最大值增大到 2^{(16+14)} – 1 = 2^{30}– 1。 窗口扩大选项可以在双方初始建立 TCP 连接时进行协商。

选项(8):时间戳。

·占 10 字节。最主要的 2 个字段:     

        时间戳值字段(4字节)和时间戳回送回答字段(4字节)。

·2 个主要功能:

        1.计算往返时间 RTT

        2.防止序号绕回 PAWS (Protect Against Wrapped Sequence numbers)。

         -序号重复时,为了使接收方能够把新报文段和迟到很久的旧报文段区分开,可以在报文段中加上时间戳。

1.5 TCP 可靠传输的实现

1.5.1 以字节为单位的滑动窗口

·TCP 使用流水线传输和滑动窗口协议实现高效、可靠的传输。

·TCP 的滑动窗口是以字节为单位的。

·发送方 A 和接收方 B 分别维持一个发送窗口和一个接收窗口

·发送窗口:在没有收到确认的情况下,发送方可以连续把窗口内的数据全部发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。

·接收窗口:只允许接收落入窗口内的数据。

 第一,发送窗口是根据接收窗口设置的,但在同一时刻,发送窗口并不总是和接收窗口一样大(因为有一定的时间滞后)。

第二,TCP 标准没有规定对不按序到达的数据应如何处理。通常是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程。

第三,TCP 要求接收方必须有累积确认的功能,以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。但接收方不应过分推迟发送确认,否则会导致发送方不必要的重传,捎带确认实际上并不经常发生。

1.5.2 超时重传时间的选择

·TCP 发送方在规定的时间内没有收到确认就要重传已发送的报文段。

·但重传时间的选择是 TCP 最复杂的问题之一。

·互联网环境复杂,IP 数据报所选择的路由变化很大,导致运输层的往返时间 (RTT) 的变化也很大。

TCP 超时重传时间设置:

·不能太短,否则会引起很多报文段的不必要的重传,使网络负荷增大。

·不能过长,会使网络的空闲时间增大,降低了传输效率。

TCP 采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应确认的时间。 这两个时间之差就是报文段的往返时间 RTT。

1.5.3 选择确认 SACK

问题:若收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么能否设法只传送缺少的数据而不重传已经正确到达接收方的数据?

解决:选择确认 SACK  (Selective ACK)。

RFC 2018 对 SACK 的规定:

·如果要使用选择确认,在建立 TCP 连接时,要在 TCP 首部的选项中加上允许 SACK 选项,且双方必须事先商定好。

·如果使用选择确认,原来首部中的确认号的用法仍然不变(累积确认)。只是在 TCP 首部中都增加了 SACK 选项,以便报告收到的不连续的字节块的边界。

1.6 TCP 的流量控制

1.6.1 利用滑动窗口实现流量控制

·流量控制 (flow control) :让发送方的发送速率不要太快,使接收方来得及接收。

·利用滑动窗口机制可以很方便地在 TCP 连接上实现对发送方的流量控制。

   利用可变窗口进行流量控制举例

死锁的解决办法——持续计时器

·持续计时器  (persistence timer):只要 TCP 连接的一方收到对方的零窗口通知,就启动该持续计时器。

        ·若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带 1 字节的数据),对方在确认这个探测报文段时给出当前窗口值。

        ·若窗口仍然是零,收到这个报文段的一方就重新设置持续计时器。

        ·若窗口不是零,则死锁的僵局就可以打破了。 

1.7 TCP 的拥塞控制

拥塞产生的原因

由许多因素引起。例如:

        节点缓存容量太小;

        链路容量不足;

        处理机处理速率太慢;

        拥塞本身会进一步加剧拥塞;

出现网络拥塞的条件:∑ 对资源需求  > 可用资源。

增加资源能解决拥塞吗?

        不能,而且还可能使网络的性能更坏。

        例如:

        增大缓存,但未提高输出链路的容量和处理机的速度,排队等待时间将会大大增加,引起大量超时重传,解决不了网络拥塞;

        提高处理机处理的速率会将瓶颈转移到其他地方;

        拥塞引起的重传并不会缓解网络的拥塞,反而会加剧网络的拥塞。

 拥塞控制与流量控制的区别

  

拥塞控制的一般原理:

        拥塞控制的前提:网络能够承受现有的网络负荷。

        实践证明,拥塞控制是很难设计的,因为它是一个动态问题。

        分组的丢失是网络发生拥塞的征兆,而不是原因。

        在许多情况下,甚至正是拥塞控制本身成为引起网络性能恶化、甚至发生死锁的原因。

1.7.1 TCP 的拥塞控制方法

·TCP 采用基于滑动窗口的方法进行拥塞控制,属于闭环控制方法。

·TCP 发送方维持一个拥塞窗口 cwnd (Congestion Window)。

·拥塞窗口的大小取决于网络的拥塞程度,并且是动态变化的。

·发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量。

·发送窗口大小不仅取决于接收方窗口,还取决于网络的拥塞状况。

·真正的发送窗口值 = Min (接收方通知的窗口值,拥塞窗口值)。

控制拥塞窗口变化的原则:

·只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,提高网络的利用率。

·但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,缓解网络出现的拥塞。

TCP 拥塞控制算法:

四种拥塞控制算法( RFC 5681) :

        ·慢开始 (slow-start)

        ·拥塞避免 (congestion avoidance)

        ·快重传 (fast retransmit)

        ·快恢复 (fast recovery)

慢开始和拥塞避免算法的实现举例

·当 TCP 连接进行初始化时,将拥塞窗口置为 1(窗口单位不使用字节而使用报文段)。

·将慢开始门限的初始值设置为 16 个报文段,即 ssthresh = 16。

·开始执行慢开始算法时,拥塞窗口 cwnd=1,发送第一个报文段。

·发送方每收到一个对新报文段的确认 ACK,就把拥塞窗口值加 1,因此拥塞窗口 cwnd 随着往返时延 RTT 按指数规律增长。

·当拥塞窗口 cwnd 增长到慢开始门限值 ssthresh 时,改为执行拥塞避免算法,拥塞窗口按线性规律增长。

·当拥塞窗口 cwnd = 24 时,网络出现了超时,发送方判断为网络拥塞。调整门限值 ssthresh = cwnd / 2 = 12,同时设置拥塞窗口 cwnd = 1,进入慢开始阶段。

·按照慢开始算法,发送方每收到一个对新报文段的确认 ACK,就把拥塞窗口值加 1。当拥塞窗口 cwnd = ssthresh = 12 时,改为执行拥塞避免算法,拥塞窗口按线性规律增大。

·当拥塞窗口 cwnd = 16 时,发送方连续收到 3 个对同一个报文段的重复确认(记为 3-ACK)。发送方改为执行快重传和快恢复算法。

·执行快重传和快恢复算法:发送方调整门限值 ssthresh = cwnd / 2 = 8,设置拥塞窗口 cwnd = ssthresh = 8,开始执行拥塞避免算法。

TCP 拥塞控制流程图

发送窗口的上限值 = Min [rwnd, cwnd] .

当 rwnd < cwnd 时,是接收方的接收能力限制发送窗口的最大值。

当 cwnd < rwnd 时,是网络拥塞限制发送窗口的最大值。

1.8 TCP 的运输连接管理

·TCP 是面向连接的协议。

·TCP 连接有三个阶段: 连接建立 数据传送 连接释放

·TCP 的连接管理就是使 TCP 连接的建立和释放都能正常地进行。

TCP 连接建立过程中要解决的三个问题

1.要使每一方能够确知对方的存在。

2.要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)。

3.能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。

TCP 连接的建立采用客户服务器方式

主动发起连接建立的应用进程叫做客户 (client)。

被动等待连接建立的应用进程叫做服务器 (server)。

1.8.1 TCP 的连接建立——三次握手

·TCP 建立连接的过程叫做握手。

·采用三报文握手:在客户和服务器之间交换三个 TCP 报文段,以防止已失效的连接请求报文段突然又传送到了,因而产生 TCP 连接建立错误。

·B 的 TCP 服务器进程先创建传输控制块 TCB,准备接受客户进程的连接请求。

·A 的 TCP 向 B 主动发出连接请求报文段,其首部中的同步位 SYN = 1,并选择序号 seq = x,表明传送数据时的第一个数据字节的序号是 x。

TCP规定,SYN 报文段(即SYN = 1的报文段)不能携带数据,但要消耗掉一个序号。

·B 的 TCP 收到连接请求报文段后,如同意,则发回确认。 B 在确认报文段中应使 SYN = 1,使 ACK = 1,其确认号 ack = x + 1,自己选择的序号 seq = y。

·A 收到此报文段后向 B 给出确认,其 ACK = 1,确认号 ack = y + 1。 A 的 TCP 通知上层应用进程,连接已经建立。

TCP 标准规定:ACK 报文段可以携带数据。 但如果不携带数据,则不消耗序号。下一个数据报文段的序号仍是 seq = x + 1。

·B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程:TCP 连接已经建立。双方可以开始数据传送。 

1.8.2 TCP 的连接释放——四次挥手

·TCP 连接释放过程比较复杂。

·数据传输结束后,通信的双方都可释放连接。

·TCP 连接释放过程是四报文握手

·A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。 A 把连接释放报文段首部的 FIN = 1,其序号seq = u,等待 B 的确认。

TCP规定:FIN 报文段即使不携带数据,也消耗掉一个序号。

·B 发出确认,ACK=1,确认号 ack = u+1,这个报文段的序号 seq = v。 TCP 服务器进程通知高层应用进程。 从 A 到 B 这个方向的连接就释放了,TCP 连接处于半关闭 (half-close) 状态。B 若发送数据,A 仍要接收。

·若 B 已经没有要向 A 发送的数据,其应用进程就通知 TCP 释放连接。 FIN=1,ACK=1,确认号 ack = u+1。

·A 收到连接释放报文段后,必须发出确认。  ACK=1,确认号 ack=w+1,自己的序号 seq = u + 1。

·请注意:此时 TCP 连接还没有释放掉。必须经过时间等待计时器 (TIME-WAIT timer) 设置的时间 2MSL 后,A 才释放 TCP 连接。

必须等待 2MSL 的时间:

第一,保证发送的最后一个 ACK 报文段能够到达 B。

第二,防止“已失效的连接请求报文段”出现在本连接中。

保活计时器

·用来防止在 TCP 连接出现长时期空闲。

·通常设置为 2 小时 。

·若服务器过了 2 小时还没有收到客户的信息,它就发送探测报文段。

·若发送了 10 个探测报文段(每一个相隔 75 秒)还没有响应,就假定客户出了故障,因而就终止该连接。 

1.9 TCP 的有限状态机

欢迎一起学习~

猜你喜欢

转载自blog.csdn.net/m0_64621282/article/details/136081494