TCP协议

本文详细介绍了TCP协议的核心特性,包括报文结构中的序号和确认号实现可靠传输,三次握手建立连接以避免半连接问题,四次挥手断开连接的过程,以及流量控制的接收窗口机制和拥塞控制的策略,如慢启动、拥塞避免和快速恢复等。
摘要由CSDN通过智能技术生成

TCP

TCP从缓存中取出的报文段中的数据量受最大报文段长度(MSS)限制。MSS通常根据数据链路层帧长度,即最大传输单元(MTU)来设置。MSS要保证一个TCP报文段加上TCP/IP首部长度是适合单个链路层帧的。由于数据链路层的MTU通常为1500字节,因此MSS的典型值为1460字节。

之所以会限制最大长度,是因为要考虑路由器的转发。路由器是分组转发的,一个报文段越长固然效率越高,但是对于检查每个报文段所需要的成本也就越高,并且丢失重传的代价也越大。

同时,TCP报文没有明确的报文界限,需要应用层来设计某些功能来区分不同的报文,例如HTTP使用两个连续的回车换行符来识别报文的界限。

报文结构

TCP报文段结构如下所示:

  • 32比特的序号字段和32比特的确认号字段:实现可靠数据传输的服务,用来表示发送的第几个字节和对第几个字节数据的确认;
  • 16比特的接收窗口字段:根据对选择重传协议的学习,可以知道窗口大小要小于等于序号范围大小的二分之一,因此为16比特。该字段用于流量控制,不让发送方发送过多数据;
  • 4比特的首部长度字段:用于指示TCP首部长度。由于TCP选项字段的原因,TCP首部的长度是可变的。通常,该选项字段为空;
  • 可选与变长的选项字段:用于发送方和接收方协商MSS,或在高速网络环境下用作窗口调节因子时使用;
  • 6比特的标志字段:
    • ACK比特用于指示确认字段中的值是有效的,即该报文段包括一个对已被成功接收报文段的确认;
    • RST/SYN和FIN比特用于连接的建立和拆除;
    • PSH比特用于表示接收方应立刻将数据交给上层;
    • URG比特用来表示报文段里存在着被发送端的实体置为“紧急”的数据
  • 16比特的紧急数据指针字段:用来指出“紧急”数据。

在这里插入图片描述

序号和确认号

TCP的序号是建立在传送的字节流之上,而不是建立在传送的报文段上。即序号代表的是传输了多少字节,而不是传输了多少个报文。

一个报文段的序号是该报文段首字节的编号。例如A向B发送一个500,000字节的文件,其MSS为1000字节。则TCP为该数据流建立500个报文段。第一个报文段分配序号0,第二个报文段分配序号1000。

在这里插入图片描述

而确认号是主机希望收到的下一字节的编号,即已经正确收到了确认号-1个字节。例如A已经收到了B的编号为0535的所有字节,A就会向B发送一个确认号为536的报文段。此外,如果A收到了来自于B的0-535以及900-1000的报文段,则会收到两个确认号为536的报文。所以TCP提供了累计确认,这也表示着发送的报文可能已经丢失。

可靠数据传输

TCP是一个可靠数据传输协议。在之前讨论SR时,对每个分组都设置了一个定时器,但定时器的管理需要相当大的开销,因此TCP只使用单一的重传定时器,即使存在多个已发送但还未被确认的报文段。

TCP发送方主要有3个事件:(1)从上层应用接收数据后,就将数据封装然后发送,如果此时没有定时器启动便启动一个定时器;(2)当定时器超时后,TCP重传最小序号但未应答的报文段,并且重启定时器;(3)当接收到确认报文段后,发送方将确认的值y与最早发送但未被确认的字节序号x进行比较。如果y>x,则更新x至y,并重启一个定时器。

  • 只有一个定时器,在具有最小序号的已发送但未确认的分组上(像GBN),因此超时只重传该分组;
  • 超时只重传最早的已发送但未确认的分组,其余已发送但未确认的分组不重传(像SR);
  • 接收方对于乱序到达的分组,没有做规定如何处理它们,可以缓存也可以丢掉;

如下图所示,当ACK=100丢失时,发送方定时器超时重发数据。

当ACK=120丢失,尽管收到了序号92的信息,仍然发送ACK=120,因为接收端确信自己已经收到了120之前的所有数据了。

在这里插入图片描述

TCP建立连接(三次握手)

之所以是三次握手,是因为二次握手可能会导致服务器维护大量半连接的问题。当发送方发送一个连接请求后,因为没有及时收到接收方的回复又重发了一次,而重发的请求则在连接断开之后到达了接收方。此时,接收方向发送方返回一个确认,但由于发送方没有向接收方发送请求,因此不做任何处理,接收方便维持了一个半连接。可能有人认为只要接收不到数据,便可以认为连接是无效的。但是与连接请求可以在连接断开后到达发送端,数据也可以在连接断开后到达发送端。因此,凭借是否到达数据来判断连接是否有效是不可行的。

在这里插入图片描述

TCP建立三次握手的流程如下:

(1)发送方将SYN位置为1,并且选择随机初始序号x发送给接收方;

(2)接收方将SYN位置为1,并且选择随机初始序号y(相当于发送方的第一步),同时将ACK位置为1,并且发送ACK=x+1给发送方(对发送方的确认);

(3)接收方将ACK位置为1,并发送ACK=y+1给接收方(对接收方的确认)

其实需要三次握手的本质是需要对接收方进行一次确认,因为接收方也向发送方发送了一些参数(初始序号,窗口大小等)。

三次握手可以解决二次握手存在的半连接问题,因为当连接断开后第一次握手到达发送方,发送发对发送方的第二次握手会被拒绝,因此建立不起连接。由于第三次握手不要求确认,因此第三次握手不会重发,即只会有一次第三次的握手,所以不会因为重发第三次握手导致断开连接后又建立起了连接。

但是存在一种情况,即老的数据在网络中滞留时间较长,在断开连接后又建立了新的连接后才到达接受端,此时接受方将老数据当做新数据看待。这也是为什么序号要随机初始化的原因,是让序号空间尽可能的变化,使得老数据的序号不会落在新的序号空间中。

在这里插入图片描述

TCP断开连接(四次挥手)

当TCP想要断开连接时,因为通信是双向的,双方都要经历断开的请求和确认,需要经历四次挥手:

(1)一方向另一方发送断开请求,将FIN位置为1;

(2)另一方确认,将ACK位置为1;

(3)另一方向发送断开请求,将FIN位置为1;

(4)一方确认,将ACK位置为1
在这里插入图片描述

流量控制

由于接收方读取速度的速率可能低于发送方发送数据的速率,因此需要告诉发送方自身能够接收数据的能力,防止发送方发送的大量分组被丢弃掉。

TCP提供了流量控制服务来消除发送方和接收方速率不匹配的问题。TCP通过让发送方维护一个接收窗口的变量来提供流量控制,该窗口用于给发送方一个指示——该接收方还有多少可用的缓冲空间。因为TCP是全双工通信,因此接收方和发送方都要各自维护一个接收窗口。

RevBuffer用于表示接收方的缓存大小,LastByteRead表示接收方从缓存中读取的数据中最后一个字节的编号,LastByteRevd表示放在接收方缓存中数据中的最后一个字节的编号。

由于TCP不允许缓存移除,因此下式必须成立:

L a s t B y t e R c v d − L a s t B y t e R e a d < = R c v B u f f e r LastByteRcvd-LastByteRead<=RcvBuffer LastByteRcvdLastByteRead<=RcvBuffer

接收窗口使用rwnd来表示,根据缓存可用的空间来设置:

r w n d = R c v B u f f e r − ( L a s t B y t e R c v d − L a s t B y t e R e a d ) rwnd=RcvBuffer-(LastByteRcvd-LastByteRead) rwnd=RcvBuffer(LastByteRcvdLastByteRead)

由于空间是变化的,所以rwnd是动态的。

在这里插入图片描述

主机通过将rwnd值放入发送给接收方的报文段的接收窗口字段中来通知接收方缓存中的可用空间。开始时,rwnd=RcvdBuffer。

拥塞控制

拥塞控制没有一个正式的定义,通常来说是由于链路中发送报文太多导致路由器无法及时处理丢包导致的。

两个发送方和一台具有无穷大缓存的路由器

主机A的发送速率是 λ i n \lambda_{in} λin,并且不执行重传。由于路由器的缓存是无限大的,因此超出路由器带宽的分组将在缓存中进行排队。

在这里插入图片描述

当发送速率在0-R/2之间时,接收方的吞度量等于发送方的发送速率。但当速率超过R/2时,吞吐量只能到达R/2,因为链路带宽是R。

在这里插入图片描述

但是对于平均时延来说,当发送速率逐渐靠近R/2后,分组便会不停地在路由器的缓存中排队,平均时延也会越来越大。

在这里插入图片描述

两个发送方和一个具有有限缓存的路由器

这里仍然以 λ i n \lambda_{in} λin作为主机A的发送速率,但此时主机会重传分组,使用 λ i n ′ \lambda_{in}^{'} λin作为初始数据+重传数据的发送速率。

在这里插入图片描述

假设主机能以某种方式得知路由器中的缓存是否控线,因此当有缓存时才发送分组,这种情况下是不会丢包的,因此 λ i n = λ i n ′ \lambda_{in}=\lambda_{in}^{'} λin=λin,每个分组也能够被接收到。在这种情况下,发送速率不能超过R/2。

在这里插入图片描述

当发送方确定了一个分组丢失后才重传, λ i n ′ > = λ i n \lambda_{in}^{'}>=\lambda_{in} λin>=λin,当 λ i n ′ \lambda_{in}^{'} λin为R/2时,其到接收方的速率可能为R/3,即0.333R是初始数据,0.166R是重传数据。

在这里插入图片描述

发送方不仅确认分组丢失后进行重传并且超时也会重传,也就是说每个分组可能被路由器转发(平均)两次,当 λ i n ′ \lambda_{in}^{'} λin位R/2时,吞吐量接近R/4。

在这里插入图片描述

4个发送方和具有有限缓存的多台路由器及多条路径

这里假设A向C传输数据,B向D传输数据,每个主机都需要经过两个路由器才能到达对方。并且A-C和B-D共享R1和R2。

在这里插入图片描述

λ i n \lambda_{in} λin很小的时候,发送方的发送速率和接收方的接收速率几乎相同。

λ i n \lambda_{in} λin很大的时候,因为距离主机B较近,R2上的缓存空间会先被B-D的分组占据,而A-C在R2上的吞吐量逐渐趋近于0。即A主机在第一跳路由器R1上成功存储了大量分组,但在R2会被抛弃掉。即主机A白白地占用了带宽,但却没有传输任何数据。

在这里插入图片描述

TCP采用了端到端的拥塞控制,网络层不会为传输层提供显式支持。网络中存在的拥塞需要通过网络行为来进行判断,并通过拥塞程度来改变发送的速率。

TCP通过一个额外的拥塞窗口变量cwnd来控制发送速率,与流量控制联合确定发送发的发送速率,即发送方中未被确认的数据量不会超过cwnd与rwnd中的最小值。

在一条TCP连接开始时,cwnd值通常为一个MSS的较小值,然后进入慢启动阶段。当接收到一个ACK后,将cwnd值调整为2,然后收到2个ACK后调整为4,并以指数增长。

结束这种指数增长的情况:

(1)当出现超时重传时,认为网络出现了拥塞,将cwnd设置为1并重新开启慢启动过程;

(2)将上一次出现拥塞的cwnd/2作为阈值ssthresh,当检测到cwnd达到或超过ssthresh时,进入拥塞避免模式;

(3)当检测到3个荣誉ACK时,进入快速重传和快速恢复状态。

拥塞避免

在进入拥塞避免状态时,cwnd的值大约为上次拥塞时的一半,此时TCP不会再对cwnd进行指数增长,而是每次增加一个MSS。而当出现超时时,会结束这种增长,将cwnd设置为1个MSS。当收到3个冗余ACK时,将ssthresh的值设置为cwnd的一半。接下来进入快速恢复状态。

快速恢复

对于引起TCP进入快速恢复的缺失报文段,对收到的每个冗余的ACK,cwnd的值都增加一个MSS。最终,当丢失报文段的一个ACK到达时,TCP在降低cwnd后进入拥塞避免状态。如果出现超时,迁移到慢启动状态。

抓包

使用命令telnet smtp.qq.com 25建立起指定端口号的tcp连接,并在建立连接后,断开连接。

在这里插入图片描述

在第一个报文段中,序列号为1426439379,确认号为0(因为发送方还没有发送信息),并且标志位只有Syn为1,表示发送方的建立连接的请求。

在这里插入图片描述

在第二个报文段中,序号为2621804820,确认序号为1426439380,恰好为第一个报文段序列号+1,标志位有ACK和Syn被设置为1,表示接收方同意确认连接的请求。

在这里插入图片描述

在第三个报文段中,序列号为1426439380,确认序号为2621804821,恰好为第二个报文段序列号+1,标志位只有ACK被设置为1,表示发送方再次确认。

在这里插入图片描述

在之后的发送的数据中,ACK标志为均置为1。

第一次挥手,接收方的序列号为2621804897,确认序号为1426439386,标志位有FIN和ACK被设置为1。
在这里插入图片描述

第二次挥手,发送方的序列号为1426439386,确认号为2621804898,标志位只有ACK被设置为1。

在这里插入图片描述

第三次挥手,发送方的序列号为1426439386,确认号为2621804898,标志位FIN和ACK被设置为1。

在这里插入图片描述

第四次挥手,接收方的序列号为2621804898,确认号为1426439387,标志位只有ACK被设置为1。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值