2_TCP的原理

本文深入探讨TCP的原理,从简单的停止等待协议出发,讲解其可靠传输但效率低下的特点,然后引入连续ARQ协议(Go-Back-N)以提高效率,同时分析TCP报文段的首部格式,最后讨论TCP如何实现可靠数据传输,包括窗口机制和处理不按顺序到达的分组策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 正式的TCP的全部原理很复杂,所以要先介绍几个简单的协议作为正式TCP协议的铺垫

  • 停止等待协议

    (1) 图示

    在这里插入图片描述

    (2) 原理

    1° 发送方每次传输一组数据后,接收方接到后,要发一条确认信息给发送方代表已经收到(两方的信息中都带着__编号__,以确定对应着哪个数据块);一组数据成功发送和确认接收后,才能发送下一组数据

    2° 发送方每发送一组数据,它就开始启动__超时定时器__,如果在超时中断到来前还没有收到确认信息,那就__重传__这组数据(所以要暂时保存那些发送出去、但是还没有收到确认消息的数据)

    3° 中途可能__出错的环节__有:发送方的数据在路上丢失、接收方的确认消息在路上丢失、虽然都没丢失但是传输超时。无论发生了哪种情况,对于每一组数据来说,必须要经过完整的发送、确认到达过程以后,才能传下一组数据,否则就是超时中断就重传

    4° 如果接收方已经接收到分组,但是确认信息没到发送方一侧,那么发送方还会重传这个分组,这时接收方接到这个重复的分组时的操作是:丢弃这个分组 + 发送确认这个分组的信息(因为这代表这个分组确认信息接收方没收到)

    5° 如果接收方的确认消息姗姗来迟,那么发送方很可能收到好几次关于同一编号分组的确认消息,此时发送方的操作是:丢弃这个确认消息(因为都已经收到过一遍确认消息了,很可能开始传下一个编号的分组了)

    (3) 停止等待协议其实中间还用到了__ARQ(Automatic Repeat reQuest,自动重传请求)。ARQ还在后面的协议中用到了,这里自动重传机制,已经保证了__停止等待协议是可靠传输的

    (4) 存在的问题:效率太低

    设发送的分组长为L,发送方发送速率为R,则发送方发送分组需要的时间 t1 = L / R;

    同理,设确认信息的分组长为l,接受方发送速率为r,则接收方发送确认信息需要的时间 t2 = l / r;

    设分组在信道中传递的__往返__时间是RTT;

    又因为停止等待协议中,不完整经过一次发送和确认的过程,下个分组永远都不会发,所以其实只有t1的时间在干正事(其实t1中还有一部分时间在传首部信息这种无效信息),所以__信道利用率__特别低

      U ≈ t1 / (t1 + RTT + t2)
    

    (5) 有了停止等待协议以后,好消息是这就是一个__可靠传输机制__,坏消息是__效率太低__

  • 连续ARQ协议(Go-Back-N)

    (1) 刚才的停止等待协议虽然可以可靠传输,但是效率太低;那解决效率太低的方法是:不要每次只传一个然后就傻乎乎的等,而是一次都传一些分组

    (2) 图示

在这里插入图片描述
(3) 原理

1° 现在发送方不是一次传一个分组了,而是一次传一群分组,它们现在也有序号,并且序号是从小到大的;

2° 图5-13(a)中黑框里面的部分称为__发送窗口__,无论是开始发送,还是超时重传,每次都发送的是发送窗口内的一群分组;

3° 现在接受方的确认机制不是每来一个分组就发一次确认消息,因为现在很可能是一群分组“纷至沓来”,所以采取__累积确认__的方法:对按顺序、无丢失达到的一组分组,对最后一个分组发送确认;

例如现在接收方发现来了序号为1,2,3,4,5的5个分组,那它就向发送方发针对5的确认信息,告诉发送方5之前的都收到了;如果接收方发现来了1,2,4,5的4个分组(3在中途丢了),那么它就针对2发送确认信息,告诉发送方2之前的都收到了

也就是说,现在的确认信息在告诉发送方,序号X和X以前的分组收到了,你不用再重传了;

4° 发送方收到接收方针对X的确认信息以后,它就会__滑动发送窗口__,使得发送窗口从X+1开始,因为X之前的已经收到了,接下来发X+1以后的分组

(4) 现在的好消息是信道利用率提高了(因为一次可以发多个分组不用每个都等),坏消息是如果信道质量有问题中间总是丢分组的话(例如发了1,2,3,4,5收到了1,3,4,5),那么还是要Go-Back-N,从2开始重发,因为2丢了,这样和每次发一次好像也没什么区别

  • TCP报文段的首部格式

    (1) 图示

    在这里插入图片描述

    固定首部是20 Byte,可选首部是4*n个Byte,长度由固定首部中的数据偏移一项指定(最大为40 Byte)

    (2) 源端口、目的端口

    (3) 序号:4 Byte --> 序号范围是 [0, 2^32 - 1]

    1° 在TCP连接中传送的字节流中的每一个字节都__按顺序编号__,直到2^32 - 1后又回到0

    2° 在TCP__连接建立__时,就要指定字节流的__起始编号__

    3° 每个TCP报文段中的序号指的都是当前报文段字节流的__起始编号__

    例如当前TCP报文段起始编号为301,而数据部分有100个字节,说明当前携带的是301-400这个100个字节

    (4) 确认号

    代表期望收到对方下一个报文段的第一个数据字节的序号

    例如确认号是701,说明接收方__已经收到了__700和700以前的字节,接下来它希望收到从701开始的字节

    2° 也是4 Byte,可以和__序号__部分对应上

    (5) 数据偏移

    4 Byte,代表TCP首部的总长度,单位是32位字(一个32位字 = 4个 Byte)

    因此,TCP首部的总长度最大值为 (2^4 - 1) * 4 = 60 Byte,去掉固定部分的20 Byte,说明可选部分的最大长度是 40 Byte

    (7) URG标志

    平时都是0,置为1的时候代表:告诉发送方操作系统,本报文段中含有紧急数据,当前报文段不应该参与排队,而是紧急发送;然后发送方TCP会把紧急数据插入到报文段数据部分的__最前面__,后面跟着的还是非紧急数据(到底有多少字节的紧急数据这个由首部中的紧急指针选项指定)

    (8) ACK标志

    ACK = 1时,__确认号__字段有效;

    ACK = 0时,确认号字段无效;

    只要连接建立,所有传送的报文段的ACK都必须置为1

    (9) PSH标志

    平时为0,置为1表示发送方想要告诉接收方,不要缓存填满再上交给进程,而是当前报文段需要被Push,立刻上交给进程

    (10) RST标志

    平时为0,置为1表示Reset,释放TCP连接然后重新建立连接

    (11) SYN标志

    平时为0,置为1表示当前报文是一个__连接请求__或__连接接受__报文

    (12) FIN标志

    平时为0,置为1表示此报文段的发送方的数据已经发送完毕,要求__释放连接__

    (13) 窗口

    1° 进行TCP连接的双方都有自己的__发送缓存__和__接收缓存__。窗口是当前报文段的发送方,在告诉接收方:我自己的接收缓存窗口有多大

    2° 如果当前报文段的确认号是701,窗口是1000,说明当前报文段的发送方想要告诉对方,你可以给我发送701-1700这么多的字节流

    3° 窗口字段明确指出了现在__允许对方发送的数据量__,经常是__动态变化__的

    (14) 检验和

    校验 TCP首部 + TCP数据段 + 伪首部(跟IP相关的部分)

    (15) 紧急指针

    在URG=1时才有意义,指出紧急数据的字节数,后面的就是普通数据了

  • TCP可靠传输的实现

    (1) Go-Back-N和TCP可靠传输已经很像了,主要区别在对那些不按顺序到达的分组的处理

    (2) 根据接收方传来的__接收窗口大小__和__网络拥塞情况__,发送方确定当前的发送窗口大小是X

    在这里插入图片描述

    (3) 发送窗口后沿的后面部分代表__已发送+已确认__,所以后沿只能前进/不动,不能后退

    (4) 发送窗口前沿的前面部分代表还不允许发送的部分,前沿可能前进(收到了窗口内的确认号,窗口整体前移);也有可能不动(确认号啥也没收到或者收到很久之前的;或者虽然窗口整体前移但是接收方要求窗口大小缩小);但是不能后退,因为有可能产生一些错误;

    图5-15中代表,接收方发过确认号31,根据接收方要求的窗口和拥塞情况判断出当前发送窗口大小应该是20

    (5) 对发送窗口可以进行进一步细分,可以用__三个指针__说明,如图5-16

    在这里插入图片描述

    P1是发送窗口后沿的指针,P3是发送窗口前沿的指针,而P2是是否已发送字节的分界线:P1——P2之间是已经发送出的字节,但是还没有收到确认信息;P2——P3之间是还没有发送出去的字节,但是它们是允许发送的;P3以后是不允许发送的

    (6) TCP的可靠数据传输机制和Go-Back-N的区别在于,对于GBN来说,只要分组没有按顺序到达,那么不按顺序的那些分组直接丢掉;而TCP的接收方有接收窗口,先把不按顺序的字节缓存下来;然后发送方接下来要发哪个字节,是根据发送窗口中的P2走,而在发送方继续发P2——P3之间字节流的过程中,完全有可能5-16中的31号字节到达接收方了,这时接收方可能很给力的发一个确认号为34的TCP报文段,然后发送方就可以愉快的前移发送窗口了,而不用像GBN一样傻乎乎的每次都必须有序,不有序的直接舍弃;

    (7) 除非是31号的确认号就是迟迟不来,那窗口位置就是动不了,P2要指向31号位置开始重传了

    (8) 缓存与窗口
    在这里插入图片描述

    窗口是缓存的一个部分,除了窗口,发送缓存还包括应用程序写入的未进入窗口的字节;接收窗口还包括应用程序未读入的但是应该按序到达的字节

    (9) 说明

    1° 缓存和序号空间都是有限的,因此都是__循环使用__的

    2° 发送窗口未必和接收方要求的一样大,因为a.网络延迟造成双方不同步 b.还要考虑网络拥塞情况

    3° 接收方有__累积确认__的功能,即攒了几个接收分组之后发一条待确认号的TCP报文段;但是攒的时间不能过长,因为会引起发送方不必要的重传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值