码迷,mamicode.com
首页 > 其他好文 > 详细

21-05-10-计网自顶向下方法

时间:2021-05-24 05:01:33      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:时间间隔   检验   应用程序   load   lock   套接字   amp   alc   握手   

3.5 面向连接的运输:TCP

3.5.1 TCP连接

面向连接:两个进程必须握手,相互发送预备报文段来确保数据传输的参数,初始化和TCO连续相关的状态变量

TCP协议在端系统中运行,中间的网络元素对连接是忽视的,看到的是数据报

TCP连接是点对点,只在连接双方

客户先发送一个特殊的TCP文段,服务器发送第二个特殊文段来响应,最后客户再用第三个特殊报文段响应,前两个文段不承载有效载荷,即不包含应用层数据,第三个报文段可以承载,此过程为三次握手

发送缓存:TCP发起三次握手期间设置的缓存之一,TCP可从缓存中取出并放入报文段中的数据量受限于最大报文段长度MSS

MSS的确定由本地发送主机发送的最大链路层帧长度(最大传输单元MTU)设置,要保证一个TCP报文段加上TCP/IP首部(40字节) 将适合单个链路层帧,一般链路层帧MTU为1500字节,于是典型的MSS设置为1460字节

MSS是指在报文段中应用层数据的最大长度,而不是包含首部的TCP报文段长度

技术图片

TCP连接组成:

发送方、接收方主机上的缓存、变量和与进程连接的套接字

3.5.2 TCP报文段结构

技术图片

MSS限制报文段数据字段的最大字段,当发送大文件时拆分成若干长度为MSS,及最后一个的数据块

  • 源端口号和目的端口号同样被用于多路复用/分解服务

  • 检验和字段:差错检测

  • 32比特的序号字段和32比特的确认号字段:可靠数据传输

  • 16比特的接收:流量控制

  • 4比特的首部长度字段:TCP首部选项不定,长度是可变的,通常选项字段为空,TCP典型长度为20字节

  • 可选与变长的选项字段:

    • 或是发送方与接收方协商的最大报文长度MSS
    • 或在高速网络用作窗口调节因子使用
    • 或时间戳
  • 6比特的标志字段:

    • ACK比特:确认字段的值是有效的
    • PSH比特:接收方应立即将数据交给上层
    • URG比特:报文段存在着被发送端的上层应用标为“紧急“的数据。紧急数据由最后一个字节由16比特的紧急数据指针字段指出,当这两个同时存在时TCP必须通知上层实体

1.序号和确认号

序号建立在字节流之上,而不是报文段的序列,对每个报文段中的字节流进行编号

假设数据流为500 000字节,MSS为1000字节,数据流首字节编号是0,第二个报文段的序号是1000,第三个是2000,以此类推

技术图片

TCP是全双工的,A向B发送数据的同时,也接收B的数据,通过同一条TCP连接

A填充进报文段的确认号是A期望从B收到的下一字节的序号

假设A已经收到了B 0 ~ 535的字节,同时要发送给B一个报文段,且等待B 536字节以及之后的字节,于是在发往B的报文段的确认号字段中填上536

假设A收到了B 0 ~ 535和900 ~ 1000的字节的报文段,但没有收到523 ~ 899字节的报文段,于是A发给B的报文段将在确认号字段中包含 536

因为TCP只确认该流中第一个字节至丢失字节为止,因此TCP被称为累积确认

TCP对收到的900 ~ 1000字节的报文段没有明确规定,交由程序员判断,两种选择:

  • 丢弃失序报文段
  • 保留失序报文段,并等待缺少的报文段来补充该间隔,此种方法对网络带宽而言更为有效,实际中采用的方法

一条TCP连接的双方均随机选择初始序号,可减少将那些在网络中存在的来自两台主机之间先前已终止的连接的报文段被误认为是后来这两台主机之间新建连接锁产生的有效报文段的可能性,在使用同端口号情况下

2.Telnet

技术图片

假设客户的起始序号是42,服务器的起始序号是79,可能经过TCP三次握手,A已经知道B的起始序号是79,于是第一个报文段的,序号是自身起始序号42,确认号则是B的起始序号,携带数据‘C‘

服务器收到客户的报文段,收到了一个字节的字节流,因此期望后续的字节,即43及以后的字节,于是回复确认号为43,向客户反馈42及之前已经收到确认,同时期望43及以后字节,而序号是初始序号,同时携带数据“C”,这种确认被认为是被捎带在服务器到客户的数据报文段中的

第三个报文段是客户发起,表示已收到79及之前的字节,同时期望80及以后数据,再由于第一个报文段已经发送了1字节的字节数据,因此序号为42

3.5.3 往返时间的估计与超时

TCP采用超时/重传机制,超时间隔必须大于该连接的往返时间RTT

1.估计往返时间

报文段样本SampleRTT:某报文段被发出到对该报文段的确认被收到之间的时间量

大多数TCP的实现仅在某个时刻做一次SampleRTT,并不是为每个发送的报文段测量

在任意时刻,仅为一个已发送但目前还没被确认的报文段估计SampleRTT,从而产生一个接近RTT的新SampleRTT

TCP不为已被重传的报文段计算SampleRTT,仅为传输一次的报文段测量SampleRTT

首先,第一次发送数据,接收方的ack在网络中丢失了,那发送方重发,然后收到ack,那么计算第一次发送的时间和收到ack的时间的时间差,显然时间算大了; 其次,第一次发送数据,接收方的ack迟到了,但没丢失,发送方重发数据后没多久,原来的ack却到了,虽是姗姗来迟但还是收到了,如果此时计算重发的时间和收到ack的时间的时间差,显然算小了。 所以对于重传的数据,不论是用第一次发送的时间还是用重传数据的时间来计算采样时间,都是存在缺陷的。

SampleRTT会随网络波动,采取以下公式更新

EstimatedRTT = (1 - a) * EstimatedRTT + a * SampleRTT
  • EstimatedRTT:SampleRTT均值
  • a推荐值:0.125 1/8
EstimatedRTT = 0.875 * EstimatedRTT + 0.125 * SampleRTT
DevRTT = (1 - B)* DevRTT + B * |SampleRTT - EstimatedRTT|
  • DevRTT:RTT误差
  • B推荐值:0.25

2.设置和管理重传超时间隔

TimeoutInterval = EstimatedRTT + 4 * DevRTT

推荐初始值为 1 秒,超时后加倍,收到报文段后则更新EstimatedRTT,再次计算TimeoutInterval

TCP使用确认和定时器来提供可靠数据传输

TCP确认正确收到的数据,当认为报文段或确认报文丢失或受损时会重传

某些版本TCP有隐式NAK机制,如快速重传机制下,收到对一个特定报文段的 3 个冗余ACK则可作为对后面报文段的隐式NAK,在超时之前重传该报文

TCP使用序号来使接收方识别丢失或重复的报文段

当TCP无法辨别报文段或ACK丢失、受损或时延过长时一律重传有疑问的报文段

TCP也使用流水线,发送方已发送但未被确认的数量由TCP的流量控制和拥塞机制决定的

3.5.4 可靠数据传输

TCP在IP不可靠的尽力而为之的服务之上创建了可靠的数据传输服务

TCP使用单一计时器来确定已发送但未确认的报文

技术图片

定时器过期时间TimeoutInterval由上小节计算而出

SendBase - 1是指接收方已经正确按序接收到的数据的最后一个字节的序号

TCP采用累积确认,y之前的字节已经收到了

如果窗口里还有已发送但还没被确认的报文段,重启定时器

1.三种情况

技术图片

第一种是确认丢失了,超时了,发送方选择重传,接收方接收后发现是冗余丢弃了,选择了再次确认

第二种是定时时间间隔太短,导致两个报文段的确认均没有在超时之前到达,发送方重传了第一段报文段,但还没有重传第二段前收到了之前两段的确认,于是放弃了重传

技术图片

发送方发送了两段报文段,接收方发送了两段确认,但第一段确认丢失了,第二段正确到达,在第一段超时时间内,此时即使没有收到第一段的确认,但第二段已确认,即第一二段已被收到,发送方因此不会重传两段报文段

2.超时间隔加倍

TCP每次超时重传报文段会将下一次超时间隔设为当前值的2倍,除非定时器移动后收到上层应用的数据或收到ACK才会使用EstimatedRTT与DevRTT计算的值

但定时器过期可能是网络拥塞导致的,而重传分组可能会使拥塞更严重,于是这种假设的TCP机制不适合,真正的TCP有更加合适的机制

3.快速重传

超时重传存在的问题是超时周期相对较长,发送方超时后再重传,增加了端到端的时延

使用冗余ACK可以较好地检测丢包

冗余ACK:再次确认某个报文段的ACK,此报文段已被发送发确认

TCP接收方的ACK生成策略:

技术图片

此表中接收方不允许丢弃失序报文段

TCP不使用NAK,在接收了失序报文段时则立即发送冗余ACK

当TCP接收了三个相同数据的冗余ACK后,TCP执行快速重传,即在该报文段的定时器过期之前重传丢失的报文段

技术图片

以上时间可代替上面的简化TCP发送方switch中的第三个事件

技术图片

4.回退N步 or 选择重传

TCP更像GBN风格,但有区别

假设1...N的报文段到达接收方,但接收方的n(n < N)ACK丢失,此时GBN会重传 n,n + 1...N分组

但TCP会重传报文段n,且如果报文段n + 1的ACK在n的超时间隔内到达甚至不会重传报文段n

TCP采用的是选择确认,允许接收方有选择地确认失序报文段,而不是累积地确认最后一个正确收到的有序报文段,看起来是GBN和SR的结合

3.5.5 流量控制

流量控制服务

  • TCP为应用程序提供了此服务来消除发送方使接收方缓存溢出的可能性

  • 速度匹配服务,发送方的发送速率与接收方应用的读取速率相匹配

  • 区分拥塞控制,由IP网络引起的,采取的动作即抑制发送方方法类似,但不是同一原因,需要区分

假设TCP接收方丢弃失序的报文段

发送方维护一个接收窗口的变量来控制流量控制,即接收窗口给发送方提示:接收方还有多少可用缓存空间

因为TCP的全双工通信,两端都同时维护着此变量

RcvBuffer:B接收方为发送方A分配的接收缓存

LastByteRead:B的应用从缓存读取的最后字节的编号

LastByteRcvd:到达且放入RcvBuffer的最后一个字节编号

rwnd:接收窗口

TCP不允许分配缓存的溢出,下式必须成立

LastByteRcvd - LastByteRead <= RcvBuffer

rwnd可用空间数量

rwnd = RcvBuffer - [LastByteRcvd - LastByteRead]

rwnd是动态,如图:

技术图片

rwnd的值被接收方B放在发给A的报文段中

开始时 rwnd = RcvBuffer,B需要跟踪几个与连接相关的变量

A轮流跟踪两个变量

  • LastByteSent:缓存中发送的最后一个字节编号
  • LastByteAcked:缓存中发送的已被确认的最后一个字节编号
  • LastByteSent - LastByteAcked:已发送但未被确认的字节量

通过将未确认数据量控制在rwnd内,可以保证A不会使B的接收缓存溢出

A在整个连接的生命周期需要保证

LastByteSent - LastByteAcked <= rwnd

存在问题:

当B的缓存满了,rwnd为0,在将此消息告诉A后,B没有消息发送给A,然后B的应用清空缓存,由于B不向A发送新报文段(TCP仅当它有数据或有确认要发时才会发送报文段给A),A无法知道B的缓存已有新空间,即A被阻塞无法再发送数据

解决:当B的接收窗口为 0 时,A继续发送只有一个字节的报文段,此报文段会被B确认,当缓存开始清空,于是B的确认报文里将有一个非 0 的rwnd值

UDP没有提供流量控制,报文段可能由于溢出在接收方丢失,

21-05-10-计网自顶向下方法

标签:时间间隔   检验   应用程序   load   lock   套接字   amp   alc   握手   

原文地址:https://www.cnblogs.com/zephxu/p/14753583.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!