TCP协议

TCP协议

TCP协议特点

与UDP协议不同TCP协议具有以下特点

  • 点对点
    • 一个发送方,一个接收方
  • 可靠的、按序的字节流
  • 流水线机制
    • TCP拥塞控制和流量控制机制设置窗口尺寸
  • 发送方/接收方缓存
  • 全双工
    • 同一连接中能够传输双向数据流
  • 面向连接
    • 通信双方在发送数据之前必须建立连接,叫做三次握手,发送数据结束后,需要关闭连接,叫做四次挥手
    • 连接状态在连接的两端中维护,在沿途节点中并不维护状态
    • TCP包括:两台主机上的缓存、链接状态变量、socket等
  • 流量控制
  • 拥塞控制

TCP报文段结构

在这里插入图片描述

  • 首部的源端口号目的端口号
    用于多路复用/多路分用来自或送到上层应用的数据
  • 32位的序号字段和32位的确认号字段
    一个报文段的序号是该报文段首字节的字节流编号。
    eg:假设主机A上的一个进程想要通过一条TCP连接向主机B上的一个进程发送一个数据流,主机A的TCP将隐式的对数据流中的每一个字节编号。假定数据流大小为5000000字节,他的最大传输单元(MSS)为1000,数据流的首字节编号为0,该TCP将为数据流建立500个报文段。给第一个报文段分配序号为0,第二个报文段分配为1000,第三个分配为2000,以此类推。每一个序号被填入到相应的TCP报文段的首部的序号字段中。
    主机A填充进报文段的确认号是主机B收到的下一字节的序号。比如主机A已经收到了来自主机B的编号为0~500的所有字节,主机A就会在它发主机B的报文段中的确认号字段中填上501
  • RUG:urgent data(不常用)紧急数据位
  • ACK:用于指示确认字段中的值是有效的
  • PSH:(push data now)将数据推到上层
  • RSH、SYN、FIN:用于比特的连接与拆除
  • CWR、ECE:在拥塞控制中会用到
  • 16比特接收窗口:该字段用于流量控制,该字段用于指示接收方愿意接收的字节数量
  • 4比特的首部长度字段:该字段指示了以32比特的字节为单位的TCP首部长度(通常,该字段为空,所以TCP首部的典型长度是20字节)
  • 可选与变长的选项字段:该字段有关于发送发与接收方协商最大报文段长度(MSS)

连接管理

建立连接

TCP是面向连接的协议,在传输数据之前,需要先建立连接
这种创建连接过程通常被称为三次握手
在这里插入图片描述

  • 第一步:客户端的TCP向服务器端发送一个特殊的TCP报文段,这个报文段不包含应用层数据,但是SYN被置为1。客户端还会随机的选择一个初始序号(client_isn)
  • 第二步:一旦包含TCP SYN报文段的IP数据报到达服务器主机,服务器就会从该数据报中取出TCP SYN报文段,为该TCP连接分配TCP缓存和变量,并向客户TCP发送允许连接的报文段。这个允许连接的报文段也不保含应用层数据。但是,SYN被置为1,其次,在TCP首部的确认字段被置为client_isn+1,最后,服务器选择自己的初始化序号(server_isn),并将其放到TCP首部的序号字段中。该允许连接的报文段被称为SYNACK报文段
  • 第三步:在收到SYNACK后,客户也要给该连接分配缓存和变量。客户端主机向服务器发送另一个报文段;折最后一个报文段对服务器的允许连接的报文段进行了确认,客户端通过将server_isn+1放到确认字段中来完成确认工作。因为连接已经建立了,所以该SYN被置为0
    完成这三次握手后,TCP连接就得以建立。(注意此次连接可以携带数据,因为客户端已经建立了)
    为什么需要三次握手?而不是两次呢?
    三次握手实际上是对双方是否拥有数据传输能力的确认,如果只有两次握手,就无法确认另一方是否具有数据传输能力

关闭连接

也被称为四次挥手

  • 一、客户端想要关闭连接,,客户TCP向服务器进程发送一个特殊的TCP报文段,此报文段FIN被置为1
  • 二、服务器接收到该报文段后,就向发送方发送一个确认报文段ACK。
  • 三、然后,服务器发送他自己的终止报文段,其FIN被置为1
  • 四、最后该客户对这个服务器的终止报文段进行确认,此时,所有的资源就都被释放了

在这里插入图片描述

  • 值得注意的是,客户机还需要等待2MSL(MSL指的是报文在网络中最大生存时间)的时间,连接才能被关闭,为什么要设置这个时间呢?
    在客户端发送对服务端的FIN确认包ACK后,这个ACK包有可能到达不了,服务器端如果接收不到ACK包就会重新发送FIN包。所以客户端发送ACK后需要留出2MSL时间(ACK到达服务器器+服务器发送FIN重传包,一来一回)等待确认服务器端缺失收到了ACK包。也就是说客户端如果等待2MSL时间也没收到服务器端重传的FIN包,则就可以确认服务器已经收到客户端发送的ACK包

  • 为什么TCP握手是三次,挥手却是四次呢?
    其实在TCP握手的时候,接收端将SYN包和ACK确认包合并到一个包中发送的,所以减少了一次包的发送。对于四次挥手,由于TCP是全双工通信,主动关闭方发送FIN请求不代表完全断开连接,只能表示主动关闭方不再发送数据了。而接收方可能还要发送数据,就不能立即关闭服务器端到客户端的数据通道,所以就不能将服务端的FIN包和对客户端的ACK包合并发送,只能先确认ACK,等服务器无需发送数据时在发送FIN包,所以四次挥手时需要四次数据包的交互

TCP的生命周期:
客户
在这里插入图片描述
服务器
在这里插入图片描述

数据传输

TCP以段的形式发送数据

TCP在传输大量数据的时候,是以MSS(Max Segment Size)的大小将数据分割发送。进行重发也是以MSS为单位。
MSS是在三次握手的时候,在两端主机之间被计算得出。两端的主机在发送建立连接的请求时,会在TCP首部写入MSS选项,告知对方自己能够接收的MSS的大小,然后会在两者之间选择一个较小的值投入使用

在这里插入图片描述

利用窗口控制提高速度

TCP以一个段位单位传输数据的话,每发一个段都要进行一次确认应答,通信性能过低。
为了解决这个问题,TCP引入了窗口这个概念,TCP以一个窗口的大小进行数据传输,窗口大小就是无需等待确认应答而可以继续发送数据的最大值。
这个机制的实现使用了大量的缓冲区。如图
在这里插入图片描述
这个窗口的大小就是四个段。
在数据发出后如期收到确认消息ACK后,此时数据就可以在缓冲区中被清除。将滑动窗口滑动到确认应答中序列号的位置
在这里插入图片描述
TCP协议与sr、GBN的区别

GBN:回退N(go back N),如果某个报文段没有被正确的接收,那么从这个报文段到后面的报文段都要重新发送,返回的ACK采用剋及确认的机制,也就是说如果GBN返回的ACK=3,也就是说3报文段和3 之前的报文段都被正确地接收了
SR:接收方设置缓冲区,为每个报文段设置计时器,如果某个报文段没有被正确接收但是后面的报文段被正确接收了(乱序到达),那么就只需要重发这一个报文段,在接收方整理排序之后就行了,返回的ACK就是当前接收成功的报文段序号
TCP:和SR类似,也有缓冲区,但是TCP有快速重传机制,不需要等待某个报文段的计时器超时才能重传,返回的ACK编号是期待接收到的下一个报文的序号
参考:https://blog.csdn.net/cobracanary/article/details/102148951

例题:
在这里插入图片描述
在这里插入图片描述
两种特殊情况:

部分ACK丢失

在发送方给接收方发送数据时,接收方发送确认包ACK,有部分ACK丢失,在TCP协议中即使有少量ACK丢失也不用重发,窗口可以通过下一个确认应答ACK进行确认。
在这里插入图片描述

报文段丢失

如下图,当某一报文丢失后,发送方会一直收到序号为1001的确认应答,如果此报文还未到达接收方,接收方就会不断地发送同一个确认应答,而发送端如果连续收到三次同一个确认应答,就会将其所对应地数据进行重发,这种机制被称为高速重发机制。
在这里插入图片描述

流量控制

接收端接收处理数据地能力是有限的,如果发送方发送数据量过快,导致接收方缓冲区被填满,此时发送方继续发送数据,就会引起不断地丢包、重传等机制,就会导致网络流量地无端浪费。
为了防止这种现象地发生,TCP提供一种机制可以让发送端根据接收端实际接受能力控制发送的数据量。这就是流控制
TCP报文结构中有一个接收窗口字段,用来通知窗口大小。
接收端向发送端通知自己可以接受数据的大小,于是发送端会发送不超过这个限度的数据,该大小限度就是窗口大小。
这个值越大,就说明网络的吞吐量越高
不过,接收端的这个缓冲区一旦面临数据溢出时,窗口大小的值也会随之改变成一个更小的值通知给发送端,从而控制数据发送量。如下图所示

在这里插入图片描述

接收端缓冲区满时,发送端会不断地向接收端发送一个窗口探测包来检测是否有窗口更新,因为窗口探测包有可能在传输地过程中丢失,所以发送方会不断地发送。

拥塞控制

一般来说, 计算机网络都处在一个共享的网络环境,因此也有可能会有因为其他主机之间的通信时的网络拥堵。在网络拥堵时,如果突然发送一个较大量的数据,,极有可能导致整个计算机网络瘫痪。为此,TCP有拥塞控制来避免这种情况的产生。
那么,我们会有三个疑问:

  1. TCP发送方如何感知从它到目的地之间的路径上存在拥堵呢?
  2. TCP发送方如何限制它相连接发送流量的速率呢?
  3. 当感知到拥堵时。采用何种算法来改变发送速率呢?
    感知拥堵
    当出现过度的拥塞时,在这条路径上的一台路由器的缓存会溢出,引起数据报被丢弃。丢弃的数据报就会引起发送方收到三个冗余ACK或者超时重传,发送方就认为在发送到接收方的路径上存在拥塞。

超时重传的情况:发送方在发送一个报文后,开启计时器,若没有收到接收方的确认报文段ACK,则对该报文进行重传

限制发送速率
通过前文我们已经知道,TCP通过窗口控制来发送数据,TCP报文中有一个接收窗口(receive window)字段用来指示窗口大小,我们把窗口大小记为rwnd,除此之外,我们还定义了一个拥塞窗口(congestion window),我们将拥塞窗口大小记为cwnd,发送方窗口的上限值实际上有这两个值中的较小的一个决定。
发 送 方 窗 口 的 上 限 值 = M i n { r w n d , c w n d } 发送方窗口的上限值=Min\begin{Bmatrix}rwnd,cwnd\end{Bmatrix} =Min{rwnd,cwnd}
下文中,我们默认rwnd无限大,故窗口大小由拥塞窗口决定

那么采用何种算法来改变发送速率呢?

慢启动

当一条TCP开始时,通常cwnd设置为一个MSS的较小值,这就使得初始发送速率大约为MSS/RTT(RTT指的是TCP报文从发送端发送报文到发送端接收到接收端的确认报文的时间)。对于TCP发送方而言,可用带宽可能比MSS/RTT大得多,因此TCP发送方需要迅速找到可用带宽的数量。因此,在慢启动阶段TCP传输报文段数量以指数级增长。
在慢启动阶段,cwnd的值以一个MSS开始增长,第一轮,cwnd = 1,第二轮拥塞窗口增长为原来的两倍,cwnd = 2,第三轮,cwnd = 4,并这样下去。
在这里插入图片描述

BUT,何时结束这种指数增长呢?
1、如果存在一个超时重发事件
TCP设有一个状态变量ssthred(slow start thred)慢启动阈值,设置为发生超时事件的cwnd/2,结束慢启动并且TCP转移到拥塞避免模式

2、如果检测到3个冗余ACK
这时,由前文可知,TCP执行快速重传,并且进入快速恢复状态

拥塞避免

一旦进入拥塞避免状态,说明可能距离拥塞可能并不遥远,因此,TCP无法再将cwnd的值翻番,而是采用了一种保守的办法。
每个RTT只将cwnd的值增加一个MSS,线性的增长。
当出现超时事件时
返回慢启动阶段,将cwnd的值设置为1个MSS,ssthred = cwnd/2
当出现3个冗余ACK时
TCP将cwnd的值减半,ssthred = cwnd/2= 2 设置拥塞窗口cwnd = ssthred = 8,执行快速恢复算法

快速恢复

与快速重传机制相配合

  1. 慢开始门限ssthresh = cwnd/
  2. 新cwnd = ssthresh
  3. 执行拥塞避免算法,是拥塞窗口缓慢地线性增大

由以上我们可以得知,忽略一条连接开始时初始的慢启动阶段,假定丢包由三个冗余ACK所指示,TCP的拥塞控制是:每个RTT内cwnd线性(加性)增加1MSS,然后出现3个冗余ACK事件时cwnd减半(乘性减)。
因此TCP拥塞控制常常被称为加性增,乘性减
下图为TCP拥塞窗口cwnd在拥塞控制时的变化情况
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值