TCP-传输控制协议


TCP 传输控制协议

前言

TCP/IP 初步架构的出现源于 1964 年,冷战时期美国国防部高级研究计划局 DARPA 提出 ARPANET 研究计划,目的是希望美国国防部的很多主机、通信控制处理机和通信线路在战争中,如部分遭到攻击而损坏时,其它部分还能正常工作,同时它希望适应从文件传送到实时数据传输的各种应用需求,因此它要求的是一种灵活的网络体系结构,实现异型网的互联 (Interconection) 与互通 (Intercomunica-tion)。
最初 ARPANET 使用的是租用线路。当卫星通信系统与通信网发展起来之后,ARPANET 最初开发的网络协议 NCP (Net Control Protocol,网络控制协议)因其在通信可靠性较差的通信子网中出现了不少问题,导致了新的网络协议 TCP/IP 的出现。虽然 TCP 协议和 IP 协议都不是 OSI 标准,但它们是目前最流行的商业化的协议,并被公认为当前的工业标准或“事实上的标准”。
1974 年 Kahn 最早定义出了的TCP/IP 参考模型(TCP/IP Reference Model)。
1985 年 Leiner 等人对该模型做了进一步的研究。
1988 年 Clark 对 该模型的设计思想进行了讨论。

TCP报文段结构

TCP报文段结构

TCP报文段各字段含义

源端口号字段、目的端口号字段:分别占16位,用于复用或分解来自或送到上层应用的数据。
首部长度字段:占4位,指出TCP段的首部长度,以4字节为计算单位,最短是20字节,最长是60字节。
保留字段:占6位,保留为今后使用,目前值为0。
标志位字段:URG、ACK、PSH、RST、SYN、FIN各占1位,各占1位,取值为0或1。
紧急URG=1,紧急指针字段有效,优先传送。
确认ACK=1,确认序号字段有效,ACK=0时,确认序号字段无效。
推送PSH=1,尽快将报文段中的数据交付接收应用进程,不要等缓存满了再交付。
复位RST=1,TCP连接出现严重差错,释放连接,再重新建立TCP连接。
同步SYN=1,该TCP报文段是一个建立新连接请求控制段或者同意建立新连接的确认段。
终止FIN=1,TCP报文段的发送端数据已经发送完毕,请求释放连接。
接收窗口字段:占16位,表示接受端的接收窗口的大小。
序号字段:占32位,TCP的序号是对每个应用层数据的每个字节进行编号。
确认序号字段:占32位,是期望从对方接收数据的字节序号,即该序号对应的字节尚未收到。
校验和字段:占16位,校验差错,TCP协议号是6。
紧急指针字段:占16位,URG=1时,才有效,指出在本TCP报文段中紧急数据共有多少个字节。
选项字段:选项字段长度可变,最短为0字节,最长为40字节。
填充字段:填充字段,取值全为0,目的是为了整个首部长度是4字节的整倍数。
数据字段:TCP数据部分

TCP连接管理

连接建立-三次握手

三次握手

第一次握手:客户向服务器发送连接请求段:(SYN=1,seq=x)
SYN=1:建立连接请求控制段。
seq=x:表示传输的报文段的第1个数据字节的序列号是x,并以此序列号代表整个报文段的序号。
客户端进入SYN_SEND(同步发送)
第二次握手:服务器收到TCP连接请求段后,如同意,则发回确认报文段:(SYN=1,ACK=1,seq=y, ack_seq=x+1)
SYN=1:同意建立新连接的确认段。
ack_seq=x+1:表示已经收到了序列号为x的报文段,准备接收序列号为x+1的报文段。
seq=y:服务器告诉客户确认报文段的序列号是y。
服务器由LISTEN进入SYN_RCVD(同步收到)
第三次握手:客户对服务器的 同意连接报文段 进行确认:(ACK=1,seq=x+1,ack_seq=y+1)
seq=x+1:客户此次的报文段的序列号是x+1。
ack_seq=y+1:客户期望接收服务器序列号为y+1的报文段。
当客户发送ACK时,客户端进入ESTABLISHED状态。
当服务收到ACK后,也进入ESTABLISHED状态。
只有第三次握手可携带数据。

连接拆除-四次挥手

四次挥手

第一次挥手:客户向服务器发送释放连接报文段:(FIN=1,seq=u)
FIN=1:发送端数据发送完毕,请求释放连接。
seq=u:传输的第一个数据字节的序号是u。
客户端状态由ESTABLISHED进入FIN_WAIT_1(终止等待1状态)
第二次挥手:服务器向客户发送确认段:(ACK=1,seq=v,ack_seq=u+1)
ACK=1:确认字号段有效。
ack_seq=u+1:服务器期望接收客户数据序号为u+1。
seq=v:服务器传输的数据序号是v。
服务器状态由ESTABLISHED进入CLOSE_WAIT(关闭等待)
客户端收到ACK段后,由FIN_WAIT_1进入FIN_WAIT_2
第三次挥手:服务器向客户发送释放连接报文段:(FIN=1,ACK=1,seq=w,ack_seq=u+1)
FIN=1:请求释放连接。
ACK=1:确认字号段有效。
ack_seq=u+1:表示服务器期望接收客户数据序号为u+1。
seq=w:表示自己传输的第一个数据字节的序号是w。
服务器状态由CLOSE_WAIT进入LAST_ACK(最后确认状态)
第四次挥手:客户向服务器发送确认段:(ACK=1,seq=u+1,ack_seq=w+1)
ACK=1:确认字号段有效。
ack_seq=w+1:表示客户期望接收服务器数据序号为w+1。
seq=u+1:表示客户传输的数据的序号是u+1。
客户端状态由FIN_WAIT_2进入TIME_WAIT,等待2MSL时间,进入CLOSED状态。
服务器在收到最后一次ACK后,由LAST_ACK进入CLOSED。

为什么需要三次握手?

第一次握手:客户发送请求,此时服务器知道客户能发。
第二次握手:服务器发送确认,此时客户知道服务器能发能收。
第三次握手:客户发送确认,此时服务器知道客户能收。

TCP可靠数据传输服务的工作机制

  1. 应用数据被分割成 TCP 认为最适合发送的数据块。
  2. TCP给发送的每一个包进行编号,TCP报文段到接收方可能会失序,接收方对数据包进行排序,把有序数据传送给应用层。
  3. TCP的接收端会丢弃重复的数据。
  4. 计时器:TCP发出一个段后,启动一个计时器,等待目的端确认收到这个报文段。
  5. 校验和:TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
  6. 流量控制:TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP使用的流量控制协议是可变大小的滑动窗口协议。(TCP 利用滑动窗口实现流量控制)
  7. 拥塞控制:当网络拥塞时,减少数据的发送。

计时器超时时间设置

TimeoutInerval = $EstimatedRTT+4×DevRTT$
EstimatedRTT:预估RTT,抽样RTT的加权移动平均值。
DevRTT:偏差RTT
EstimatedRTT:计算机网络中TCP协议对下一个数据往返值进行的估计,并利用此估计值来判断数据超时时间。
EstimatedRTT = $(1-x)×EstimatedRTT+x×SampleRTT$
其中SampleRTT为上一个数据的实际往返时间,x的值一般默认取0.125。

TCP采用累积确认策略生成ACK

  1. 具有所期望序号的报文段按序到达,所有在期望序号及以前的报文段都已被确认。TCP延迟500ms发送ACK。
  2. 具有所期望序号的报文段按序到达、且另一个按序报文段在等待ACK传输,TCP接收方立即发送单个累计ACK,确认以上两个按序到达报文段。
  3. 拥有序号大于期望序号的失序报文段到达,TCP接收方立即发送重复ACK,指示下一个期望接收字节的序号。
  4. 收到一个报文段,部分或完全填充接收数据间隔。

流量控制

发送方

接收方

  • 双方在通信的时候,发送方的速率与接收方的速率是不一定相等,如果发送方的发送速率太快,会导致接收方处理不过来,这时候接收方只能把处理不过来的数据存在缓存区里(失序的数据包也会被存放在缓存区里),如果缓存区满了发送方还在疯狂着发送数据,接收方只能把收到的数据包丢掉,大量的丢包会极大着浪费网络资源,因此,我们需要控制发送方的发送速率,让接收方与发送方处于一种动态平衡,所以针对发送方发送速率的控制,我们称之为流量控制。
  • 接收方每次收到数据包,可以在发送确定报文的时候,同时告诉发送方自己的缓存区还剩余多少是空闲的,我们也把缓存区的剩余大小称之为接收窗口大小,用变量win来表示接收窗口的大小,发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据,防止出现大量丢包情况的发生。

停等协议

  • 接受方的窗口和发送方的窗口大小都是1,这就是停等协议也叫1比特滑动窗口协议。发送方这时自然发送每次只能发送一个,并且必须等待这个数据包的ACK,才能发送下一个。虽然在效率上比较低,带宽利用率明显较低,不过在网络环境较差,或是带宽本身很低的情况下,还是适用的。
  • 存在的问题是,当发送方交替发送标记为“奇数”和“偶数”的数据包。发送的确认同样为“奇数”和“偶数”。假设已经发送了奇数分组的发送方没有收到奇数确认,而是立即发送下一个偶数分组,在此之后它可能会收到一个确认,为“下一个奇数包”。这将使发送方出现不确定因素:接收方有可能接收到这两个数据包,或者两者都没接收到。

滑动窗口协议(Sliding Window Protocol)

属于TCP协议的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生,该协议允许发送方在停止并等待确认前发送多个数据分组,由于发送方不必每发一个分组就停下来等待确认。因此该协议可以加速数据的传输,提高网络吞吐量。

回退n步协议(GO-BACK-N)
  • 由于停止等待协议效率太低,因此有了回退n步协议,这也是滑动窗口协议真正的用处,这里发送的窗口大小为n,接受方的窗口仍然为1。
  • 这里假设n=10:首先发送方一口气发送9个数据帧,前面两个帧正确返回了,数据帧2出现了错误,这时发送方被迫重新发送2-8这7个帧,接受方也必须丢弃之前接受的3-8这几个帧。
  • 回退n步协议的好处无疑是提高了效率,但是一旦网络情况糟糕,则会导致大量数据重发,反而不如停等协议。
  • 存在的问题在于,假设我们使用3位序列号,这是HDLC的典型值。这使得N==8。由于wr=1,我们必须限制wt≤7,这是因为在发送7个数据包之后,有8个可能的结果:0到7个数据包都可能被成功地接收,这有8种可能性,发送方在确认中需要足够的信息来区分它们,如果发送方发送8个数据包而不等待确认,则可能会发现自己存在和停止等待协议一样的问题,这意味着所有8个数据包都可能被成功接收,亦或是一个都没有被成功接收。
选择重传协议(selective repeat)
  • 回退n步协议的另外一个问题是,当有错误帧出现后,总是要重发该帧之后的所有帧,毫无疑问在网络不是很好的情况下会进一步恶化网络状况。
  • 选择重传协议便是用来解决这个问题。原理也很简单,接收端总会缓存所有收到的帧,当某个帧出现错误时,只会要求重传这一个帧,只有当某个序号后的所有帧都正确收到后,才会一起提交给高层应用,选择重传协议的缺点在于接受端需要更多的缓存。
  • 存在的问题在于:最为普遍的HDLC协议使用3位序列号,并具有选择性重复的可选条件,但是,如果使用选择性重复,则必须保持$nt+nr≤8$的要求;如果wr增加到2,则wt必须降低到6。假设wr=2,但是与wt=7一起使用未修改的发射机,进一步假设接收器以nr=ns=0开始。

TCP拥塞控制

TCP拥塞控制:慢启动,拥塞避免,快速重传,计时器超时,快速恢复

  1. 慢启动:在TCP连接建立时,每经过1个RTT时间,拥塞窗口增大一倍。
  2. 拥塞避免:当拥塞窗口大于等于阈值时,每经过1个RTT,拥塞窗口的值加1。
  3. 快速重传:接收端收到3次重复确认,则推断被重复确认的报文段已经丢失,于是立即发送被重复确认的报文段。
  4. 计时器超时:新的拥塞窗口:直接调整为1MSS。新的拥塞窗口=1MSS,调整好新的阈值和新的拥塞窗口后,使用慢启动,拥塞避免算法增加拥塞窗口大小。
  5. 快速恢复:当发生3次重复确认时,网络拥塞程度不是很严重,阈值和拥塞窗口的调整方法:不再重新从慢启动阶段开始,而是直接从新的阈值开始,直接进入拥塞避免阶段。

发生快速重传或计时器超时
当前拥塞窗口为24MSS,当前阈值为16MSS。
新的阈值:为当前拥塞窗口的一半。新的阈值= 24MSS÷2=12MSS

快速重传

3次重复确认

计时器超时

计时器超时

和式增加,积式减少

和式增加,积式减少(additive-increase/multiplicative-decrease,AIMD,这里简称“线增积减”)是一种反馈控制算法,其包含了对拥塞窗口线性增加,和当发生拥塞时对窗口积式减少,多个使用AIMD控制的TCP流最终会收敛到对线路的等量竞争使用。

参考资料

滑动窗口协议
https://baike.baidu.com/item/滑动窗口协议
论文:张凯,广东省湛江师范学院,TCP/IP 网络通信协议的实现与探讨


文章作者: Baymax
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Baymax !
评论
  目录