软考-中级-网络工程师(9-2)

114 阅读14分钟

TCP协议

特点:

  • 面向连接的传输层协议
  • 每一条TCP连接只有2个端点
  • 可靠交付
  • 全双工通信(发送时可以接收数据)
  • 面向字节流

TCP报文格式:

image.png

上图中 TCP 报文中每个字段的含义如下:

源端口和目的端口字段

  • TCP源端口(Source Port):源计算机上的应用程序的端口号,占 16 位。
  • TCP目的端口(Destination Port):目标计算机的应用程序端口号,占 16 位。

序列号字段

TCP序列号(Sequence Number):占 32 位。它表示本报文段所发送数据的第一个字节的编号。

在 TCP 连接中,所传送的字节流的每一个字节都会按顺序编号。

当SYN标记不为1时,表明这是当前数据分段第一个字母的序列号;

如果SYN的值是1时,这个字段的值就是初始序列值(ISN),用于对序列号进行同步。这时,第一个字节的序列号比这个字段的值大1,也就是ISN加1。

确认号字段

TCP 确认号(Acknowledgment Number,ACK Number):占 32 位。它表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。其值是接收计算机即将接收到的下一个序列号,也就是下一个接收到的字节的序列号加1。

数据偏移字段

数据偏移是TCP的首部长度。 TCP 首部长度(Header Length):数据偏移是指数据段中的“数据”部分起始处距离 TCP 数据段起始处的字节偏移量,占 4 位。其实这里的“数据偏移”也是在确定 TCP 数据段头部分的长度,告诉接收端的应用程序,数据从何处开始。

保留字段

保留(Reserved):占 4 位。为 TCP 将来的发展预留空间,目前必须全部为 0。

标志位字段

  • CWR(Congestion Window Reduce):拥塞窗口减少标志,用来表明它接收到了设置 ECE 标志的 TCP 包。并且,发送方收到消息之后,通过减小发送窗口的大小来降低发送速率。
  • ECE(ECN Echo):用来在 TCP 三次握手时表明一个 TCP 端是具备 ECN 功能的。在数据传输过程中,它也用来表明接收到的 TCP 包的 IP 头部的 ECN 被设置为 11,即网络线路拥堵。
  • URG(Urgent):表示本报文段中发送的数据是否包含紧急数据。URG=1 时表示有紧急数据。当 URG=1 时,后面的紧急指针字段才有效。
  • ACK:表示前面的确认号字段是否有效。ACK=1 时表示有效。只有当 ACK=1 时,前面的确认号字段才有效。TCP 规定,连接建立后,ACK 必须为 1。
  • PSH(Push)推送指针:告诉对方收到该报文段后是否立即把数据推送给上层。如果值为 1,表示应当立即把数据提交给上层,而不是缓存起来。
  • RST 重置指针:表示是否重置连接。如果 RST=1,说明 TCP 连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接
  • SYN同步指针:在建立连接时使用,用来同步序号。当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段;当 SYN=1,ACK=1 时,表示对方同意建立连接。SYN=1 时,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才为 1。
  • FIN终止指针:标记数据是否发送完毕。如果 FIN=1,表示数据已经发送完成,可以释放连接。

窗口大小字段

窗口大小(Window Size):占 16 位。它表示从 Ack Number 开始还可以接收多少字节的数据量,也表示当前接收端的接收窗口还有多少剩余空间。该字段可以用于 TCP 的流量控制。

TCP 校验和字段

校验位(TCP Checksum):占 16 位。它用于确认传输的数据是否有损坏。发送端基于数据内容校验生成一个数值,接收端根据接收的数据校验生成一个值。两个值必须相同,才能证明数据是有效的。如果两个值不同,则丢掉这个数据包。Checksum 是根据伪头 + TCP 头 + TCP 数据三部分进行计算的。

紧急指针字段

紧急指针(Urgent Pointer):仅当前面的 URG 控制位为 1 时才有意义。它指出本数据段中为紧急数据的字节数,占 16 位。当所有紧急数据处理完后,TCP 就会告诉应用程序恢复到正常操作。即使当前窗口大小为 0,也是可以发送紧急数据的,因为紧急数据无须缓存。

可选项字段

选项(Option):长度不定,但长度必须是 32bits 的整数倍。

TCP和UDP的对比:

image.png

image.png

TCP三次握手

TCP 是面向连接的协议,所以每次发出的请求都需要对方进行确认。TCP 客户端与 TCP 服务器在通信之前需要完成三次握手才能建立连接

image.png TCP三次握手过程如下:

第一次握手建立连接时,客户端向服务器发送SYN报文(SEQ NUM=X,SYN置位1),并进入SYN_SENT状态,等待服务器端确认

image.png 第三次握手是客户端收到服务器回复的SYN+ACK报文后,客户端也要向服务器端回复ACK报文,SEQ NUM=X+1; ACK NUM=Y+1; ACK位置为1

image.png

TCP的四次挥手

当客户端与服务器不再进行通信时,都会以 4 次挥手的方式结束连接。

TCP四次挥手过程如下

image.png

第一次挥手:客户端想服务器端发送断开TCP连接的请求FIN和ACK置位为1的报文,在报文中随机生成一个序列号SEQ Num=X,表示要断开TCP连接

image.png 第二次挥手:当服务器端收到客户端发来的断开TCP连接的请求后,回复发送ACK置位为1的报文,表示已经收到断开请求,回复时随机生成一个序列号SEQ Num=Y,ACK Num=X+1。

image.png

第三次挥手:服务器端在回复完客户端的TCP断开请求后,不会马上进行TCP连接的断开。服务器端会先确认断开前所有传输到客户端的数据是否已经传输完毕,确认数据传输完毕后才进行断开,这是会向客户端发送FIN和ACK置位为1的报文。再次随机生成一个SEQ Num=Z的报文,针对之前客户端发来的TCP断开请求的SEQ Num=X进行回复,因此新发送的ACK中ACK Num=X+1

image.png

第四次挥手:客户端收到服务器发来的TCP断开连接数据包后将进行回复,表示收到断开TCP连接数据包。向服务器发送ACK报文,生成一个SEP Num=X+1,由于回复的是服务器,所以ACK字段值在服务器发来的断开TCP连接请求SEQ Num=Z基础上加1,得到ACK Num=Z+1

image.png

流量控制(滑动窗口机制)

但是现实中确实会存在一些限制:

  • 接收方的缓存(接收窗口)可能已经满了,无法接收数据。
  • 网络的带宽也不一定足够大,一口发太多会导致丢包事故。

发送方要知道接收方的接收窗口和网络这两个限制因素中哪一个更严格,然后在其限制范围内尽可能多发包。这个一口气能发送的数据量就是传说中的TCP发送窗口。

首先TCP在进行数据传输的时候都是先将数据放在数据缓冲区中的,TCP维护了两个缓冲区,发送方缓冲区和接收方缓冲区。

  • 发送方缓冲区:发送方缓冲区用于存储已经准备就绪数据和发送了但是没有被确认的数据。
  • 接收方缓冲区:接收方缓冲区用于存储已经被接收但是还没有被用户进程消费的数据。

滑动窗口机制是TCP的一种流量控制方法,该机制允许发送方在停止并等待确认前连续发送多个分组,而不必每发送一个分组就停下来等待确认,从而增加数据传输的速率提高应用的吞吐量。

image.png TCP的包可以分为四种状态

  • 已发送并且已经确认的包。
  • 已发送但是没有确认的包。
  • 未发送但是可以发送的包。
  • 不允许被发送的包。

滑动窗口协议的基本工作流程就是由接收方通告窗口的大小,这个窗口称为提出窗口,也就是接收方窗口

接收方提出的窗口则是被接收缓冲区所影响的,如果数据没有被用户进程使用那么接收方通告的窗口就会相应得到减小,发送窗口取决于接收方窗口的大小。

可用窗口的大小等于接收方窗口减去发送但是没有被确认的数据包大小。 滑动窗口机制示意流量图

image.png

image.png

零窗口(TCP Zero Window)

在接收方窗口大小变为0的时候,发送方就不能再发送数据了。但是当接收方窗口恢复的时候发送方要怎么知道呢?

在这个时候TCP会启动一个零窗口(TCP Zero Window)定时探测器,向接收方询问窗口大小,当接收方窗口恢复的时候,就可以再次发送数据。

拥塞控制

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况就叫做网络拥塞。

image.png 在计算机网络中数位链路容量(即带宽)、交换结点中的缓存和处理机等,都是网络的资源。

若出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降。

当输入的负载到达一定程度 吞吐量不会增加,即一部分网络资源会丢失掉,网络的吞吐量维持在其所能控制的最大值,转发节点的缓存不够大这造成分组的丢失是拥塞的征兆。 TCP的四种拥塞控制算法

  • 1.慢开始
  • 2.拥塞控制
  • 3.快重传
  • 4.快恢复

假定:

  • 1.数据是单方向传送,而另一个方向只传送确认
  • 2.接收方总是有足够大的缓存空间,因而发送发发送窗口的大小由网络的拥塞程度来决定
  • 3.以TCP报文段的个数为讨论问题的单位,而不是以字节为单位

image.png 示例如下: 传输轮次:发送方给接收方发送数据报文段后,接收方给发送方发回相应的确认报文段,一个传输轮次所经历的时间就是往返时间RTT(RTT并非是恒定的数值),使用传输轮次是为了强调,把拥塞窗口cwnd所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个报文段的确认,拥塞窗口cwnd会随着网络拥塞程度以及所使用的拥塞控制算法动态变化。

在tcp双方建立逻辑链接关系时, 拥塞窗口cwnd的值被设置为1,还需设置慢开始门限ssthresh,在执行慢开始算法时,发送方每收到一个对新报文段的确认时,就把拥塞窗口cwnd的值加一,然后开始下一轮的传输,当拥塞窗口cwnd增长到慢开始门限值时,就使用拥塞避免算法。

慢开始:

假设当前发送方拥塞窗口cwnd的值为1,而发送窗口swnd等于拥塞窗口cwnd,因此发送方当前只能发送一个数据报文段(拥塞窗口cwnd的值是几,就能发送几个数据报文段),接收方收到该数据报文段后,给发送方回复一个确认报文段,发送方收到该确认报文后,将拥塞窗口的值变为2,

发送方此时可以连续发送两个数据报文段,接收方收到该数据报文段后,给发送方一次发回2个确认报文段,发送方收到这两个确认报文后,将拥塞窗口的值加2变为4,发送方此时可连续发送4个报文段,接收方收到4个报文段后,给发送方依次回复4个确认报文,发送方收到确认报文后,将拥塞窗口加4,置为8,发送方此时可以连续发送8个数据报文段,接收方收到该8个数据报文段后,给发送方一次发回8个确认报文段,发送方收到这8个确认报文后,将拥塞窗口的值加8变为16,

当前的拥塞窗口cwnd的值已经等于慢开始门限值,之后改用拥塞避免算法。

拥塞避免:

也就是每个传输轮次,拥塞窗口cwnd只能线性加一,而不是像慢开始算法时,每个传输轮次,拥塞窗口cwnd按指数增长。同理,16+1……直至到达24,假设24个报文段在传输过程中丢失4个,接收方只收到20个报文段,给发送方依次回复20个确认报文段,一段时间后,丢失的4个报文段的重传计时器超时了,发送发判断可能出现拥塞,更改cwnd和ssthresh.并重新开始慢开始算法,如图所示:

image.png

image.png

快速重传:

发送方发送1号数据报文段,接收方收到1号报文段后给发送方发回对1号报文段的确认,在1号报文段到达发送方之前,发送方还可以将发送窗口内的2号数据报文段发送出去,接收方收到2号报文段后给发送方发回对2号报文段的确认,在2号报文段到达发送方之前,发送方还可以将发送窗口内的3号数据报文段发送出去,

假设该报文丢失,发送方便不会发送针对该报文的确认报文给发送方,发送方还可以将发送窗口内的4号数据报文段发送出去,接收方收到后,发现这不是按序到达的报文段,因此给发送方发送针对2号报文段的重复确认,表明我现在希望收到的是3号报文段,但是我没有收到3号报文段,而收到了未按序到达的报文段,发送方还可以将发送窗口中的5号报文段发送出去,接收方收到后,发现这不是按序到达的报文段,因此给发送方发送针对2号报文段的重复确认,表明我现在希望收到的是3号报文段,但是我没有收到3号报文段,而收到了未按序到达的报文段,,发送方还可以将发送窗口内的最后一个数据段即6号数据报文段发送出去,接收方收到后,发现这不是按序到达的报文段,因此给发送方发送针对2号报文段的重复确认,表明我现在希望收到的是3号报文段,但是我没有收到3号报文段,而收到了未按序到达的报文段,

此时,发送方收到了累计3个连续的针对2号报文段的重复确认,立即重传3号报文段,接收方收到后,给发送方发回针对6号报文的确认,表明,序号到6为至的报文都收到了,这样就不会造成发送方对3号报文的超时重传,而是提早收到了重传。

image.png

image.png

image.png