您的位置:首页 > 理论基础 > 计算机网络

TCP/IP协议学习笔记(二)

2020-03-06 18:57 846 查看

传输层 TCP协议

本文主要整理TCP协议的知识点

1 前言

尽管TCP和UDP都使用相同的网络层(IP), TCP却向应用层提供与UDP完全不同的服务。TCP提供一种面向连接的、可靠的字节流服务。

TCP具有以下特点

1、面向连接 每个TCP段都包含一个源端口号和目的端口号,用来确定发送端和接收端的应用进程,然后结合IP首部中的源端IP地址和目的端IP地址就能唯一确定一个TCP连接。

2、可靠 TCP协议拥有各种机制来确保数据传送的可靠性,例如超时重传策略,保持首部和数据的校验和,流量控制和校验已收到数据的完整性和正确性等。

2 TCP首部

TCP报文段被封装到IP数据报中,通常是20个字节。

源端口号和目的端口号:用于寻找发送端和接收端的应用进程,分别是16位

Sequence Number(序列号):报文段中的第一个字节,用于标识发送的数据字节流

Acknowledgment Number(确认号):确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志为1时该确认序列号的字段才有效。

Offset(数据偏移):给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节;

TCP Flags:TCP首部中有6个标志比特,它们中的多个可同时被设置为1,主要是用于操控TCP的状态机的,依次为URG,ACK,PSH,RST,SYN,FIN。每个标志位的意思如下:

URG:此标志表示TCP包的紧急指针域有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据;

ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;

PSH:这个标志位表示Push操作。该标志通知接收方将接收到的数据全部提交给接收进程。这里所说的数据包括与此PUSH包一起传输的数据以及之前就为该进程传输过来的数据。

RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;

SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手;

FIN:用来结束一个TCP回话.但对应端口仍处于开放状态,准备接收后续数据。

Window(窗口大小):窗口大小,也就是有名的滑动窗口,用来进行流量控制。

CheckSum(校验和):检验和是一个强制性字段,是由发送端计算和保存,然后由接收端进行校验

Urgent Pointer(紧急指针):只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。

TCP数据部分是可选的,在建立和终止连接等情况下就会发送不带数据部分的报文段

3 TCP连接

TCP是一个面向连接的协议,一方向另一方发送数据,必须先在双方之间建立一条连接。

3.1 TCP连接建立和断开

  1. 客户端执行主动打开操作,向服务端发送SYN报文,指明打算连接的服务端的端口,以及初始序号(ISN),然后进入SYN_SENT状态。其中ISN随时间而变化,所以不同的连接都将具有不同的ISN。
  2. 服务端收到SYN报文后,同样向客户端发回一个带有自己初始序号的SYN报文段,同时将ACK字段设为客户端ISN+1的值,作为对客户端SYN报文的确认响应,然后自己进入SYN_RCVD状态。
  3. 客户端同样将ACK字段设为服务端ISN+1的值,作为对服务端SYN报文的确认响应,自己进入ESTABLISHED状态,服务端收到客户端的确认响应后,也进入ESTABLISHED状态。

连接建立成功后,双方则能够发送数据,接收方则发送ACK报文作为确认响应。

TCP连接的断开—四次挥手

建立连接需要三次交互,而断开连接则需要四次交互,这是由于TCP连接是一个全双工连接,需要双方单独来进行关闭,收到FIN报文意味着在这个方向上没有数据流动,但是仍然可以发送数据。

  1. 应用关闭,需要断开TCP连接,则向服务端发送FIN报文,并进入FIN_WAIT_1状态;
  2. 服务端收到客户端发送的FIN请求,则回发ACK,ACK序列号为ACK加1,进入CLOSE_WAIT状态;客户端收到ACK确认回应后,进入FIN_WAIT_2状态。此时,客户端无法发送数据,但是仍可接收服务端发来的数据,这种状态称为半关闭状态。
  3. 服务端不需要发送数据时,则向客户端发送FIN请求断开连接,进入LAST_ACK状态,客户端收到断开请求,回应ACK,进入TIME_WAIT状态;服务端收到ACK后,进入CLOSED,从此TCP连接成功断开。

3.2 TCP状态迁移

TCP所谓的“连接”,其实是通讯双方维护的一种状态,看上去像是连接一样,这就涉及到TCP连接过程中,通讯双方不同状态的装换。

  1. TIME_WAIT 状态
    也称为2MSL等待状态,每个具体TCP实现必须选择一个报文段最大生存时间MSL。它是任何报文段被丢弃前在网络内的最长时间。对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。

  2. FIN_WAIT_2 状态
    在FIN_WAIT_2状态我们已经发出了 FIN,并且另一端也已对它进行确认。除非我们在实行半关闭,否则将等待另一端的应用层意识到它已收到一个文件结束符说明,并向我们发一个 FIN 来关闭另一方向的连接。只有当另一端的进程完成这个关闭,我们这端才会从FIN_ WAIT_2状态进入TIME_WAIT状态。
    这意味着我们这端可能永远保持这个状态。另一端也将处于 CLOSE_WAIT状态,并一直保持这个状态直到应用层决定进行关闭。

3.3 复位报文段

TCP首部中的RST位,用于“复位”,主要在下列三个场景中:

  1. 到不存在的端口的连接请求
    当连接请求到达时,目的端口没有进程正在监听,这个时候,就会发回RST报文告诉请求端;
  2. 异常终止一个连接
    客户端断开连接时,有可能不是通过发送FIN报文,而是发送RST进行复位,这称为异常释放。异常终止一个连接对应用程序来说有两个优点:丢弃任何待发数据并立即发送复位报文段;RST的接收方会区分另一端执行的时异常关闭还是正常关闭。
  3. 检测半打开连接
    如果一方已经关闭或异常终止连接而另一方却还不知道,我们将这样的 T C P连接称为半
    打开。 任何一端的主机异常都可能导致发生这种情况。只要不打算在半打开连接上传输数据,仍处于连接状态的一方就不会检测另一方已经出现异常。

3.4 同时打开和关闭

两个应用程序同时彼此执行主动打开的情况是可能的,尽管发生的可能性极小。每一方必须发送一个 SYN,且这些SYN必须传递给对方。 这又称为同时打开。

当出现同时打开的情况时,两端几乎在同时发送 SYN,并进入SYN_SENT状态。当每一端收到 SYN时,状态变为 SYN_RCVD,同时它们都再发SYN并对收到的 SYN进行确认。当双方都收到 SYN及相应的ACK时,状态都变迁为ESTABLISHED 。一个同时打开的连接需要交换4个报文段,比正常的三次握手多一个。

当应用层发出关闭命令时,两端均从ESTABLISHED变为FIN_WAIT_1。这将导致双方各发送一个FIN,两个FIN经过网络传送后分别到达另一端。收到FIN后,状态由FIN_WAIT_1变迁到 CLOSING,并发送最后的 ACK。当收到最后的 ACK时,状态变化为TIME_WAIT 。同时关闭和正常关闭使用的段交换数目相同。

4 TCP数据传输

TCP与UDP的区别相当大,它充分体现了数据传输时各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。TCP通过校验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。

4.1 成段数据流

在建立TCP连接的同时,也可以确定发送数据包的单位,我们也可以称为“最大消息长度”(MSS:Maximum Segment Size),最理想的情况时,最大消息长度正好是IP中不会被分片处理的最大数据长度。

TCP在发送数据时,会以MSS大小为单位对数据进行分割发送。MSS大小在三次握手时计算所得,两端发送建立连接的请求时,会在TCP首部中写入MSS选项,选两者较小的值。

4.2 滑动窗口控制

TCP以一个段为单位发送数据,每发送一个段就会接收到一个确认应答的处理,这样容易造成传输负载变重,段的往返时间越长,性能越低。为了解决这一缺点,TCP引入了“窗口”的概念,发送端在发送了一个报文段后不必要一直等待确认应答,而是继续发送。

窗口大小指无需等待确认应答而可以继续发送数据的最大值,图中窗口大小是4个报文段。

该图①中,可以看到滑动窗口的大小是4个报文段,报文段1001以前,接收端已经确认应答,报文段5001是未发送的数据,中间的报文段则是已经发送完成,正在等待确认应答的部分。当接收端确认数据后,这个滑动窗口不断的往右移动,窗口两个边沿的相对运动增加或减少了窗口的大小。

  1. 窗口左边沿向右边沿靠近为窗口合拢。这种现象发生在数据被发送和确认时。
  2. 窗口右边沿向右移动,将允许发送更多的数据,称为窗口张开。这种现象发生在接收端读取了已经确认的数据并释放了TCP的接收缓存。图③中则说明发送端已经收到了接收端的确认应答,窗口向右移动。

如果左边沿达到右边沿,则称为一个零窗口,此时发送方不能够发送任何数据。

4.2 超时重发和窗口控制

TCP提供可靠的运输层。
它使用的方法之一就是确认从另一端收到的数据。但数据和确认都有可能会丢失。 TCP通过在发送时设置一个定时器来解决这种问题。如果当定时器溢出时还没有收到确认,它就重传该数据。 当使用了窗口控制,某些确认应答即便丢失也无需重发。

其次,当某一个报文段在传输的过程中丢失,接收端如果收到一个自己应该接收序号以外的数据时,会针对当前为止收到的数据返回确认应答,通知发送端下一个要发送的数据序号,如果发送端连续3次收到同一个确认应答,则会对其对应的数据进行重发,无需等待超时定时器溢出,这就是快速重传算法。

有这样一种场景,发送端按照自己的实际情况来发送数据,但是接收端可能处理数据包的能力比较弱,或者一直在处理其他事情,无法接收任何的数据,此时,发送端发来的数据就会被丢弃,从而又会触发重发机制,造成资源的浪费。

为了解决这个问题,TCP提供了一种机制,可以让发送端根据接收端的实际接收能力来控制发送的数据量,这就是流控制。在TCP首部中,有专门的字段来通知窗口的大小。在接收端发送确认应答报文时,会在窗口大小字段中标明自己目前的接收能力。不过,接收端的这个缓存区一旦溢出,窗口大小的值随即被设置为一个更小的值来通知给发送端。这就形成了一个完整的TCP流控制。

如果接收端发送的窗口更新通知丢失,则双发可能因为等待对方而使连接终止:发送方等待允许它继续发送数据的窗口更新,接收方等待接收数据。这样就会造成死锁,导致无法继续通信,为避免此类问题的发生,发送端使用一个坚持定时器,定时发送一个窗口探测数据段,以获取最新的窗口大小的值。

4.3 拥塞控制

有了TCP的窗口控制,收发主机之间即使不再以一个数据段为单位发送确认应答,也能够连续发送大量数据包,但在网络出现拥堵时,突然发送一个较大的数据,极有可能导致整个网络的瘫痪。为了防止该问题出现,TCP引入了“拥塞窗口”概念,并且通过“慢启动”算法,用来调节发送端所要发送的数据量。

当建立TCP连接时,拥塞窗口被初始化为1个报文段,每收到一个ACK,拥塞窗口的值就加1,在发送数据包时,将拥塞窗口的大小和接收端的通知窗口大小做比较,取较小的值,发送比该值还要小的数据量。随着包的往返发送,拥塞窗口以指数函数增长,拥堵状况激增,可能导致网络拥塞的发生。为了解决该问题,TCP引入了“慢启动阈值”的概念,当拥塞发生(超时或收到重复确认) 时,将慢启动阈值设置成拥塞窗口的一半,只要拥塞窗口的值超出这个阈值,则只允许以下面比例放大拥塞窗口:

此外,如果是超时引起了拥塞,则拥塞窗口被设置为1个报文段(这就是慢启动)。当新的数据被对方确认时,就增加拥塞窗口,但增加的方法依赖于我们是否正在进行慢启动或拥塞避免。如果拥塞窗口小于或等于慢启动阈值,则正在进行慢启动,否则正在进行拥塞避免。慢启动一直持续到我们回到当拥塞发生时所处位置的一半的时候才停止,然后转为执行拥塞避免。

4.4 提高网络利用率

  1. Nagle算法
    该算法是指发送端即使还有应该发送的数据,但是如果这部分数据很少的话,则延迟发送。仅在满足以下两种条件中任意一种条件才能发送数据,否则暂时等待:
    已发送的数据都已经收到确认应答;
    可以发送最大段长度MSS的数据。
  2. 延迟确认应答
    如果接收端每次立刻回复确认应答,可能会返回一个较小的窗口,因为刚接收完数据,缓存区已满。当发送端收到这个较小的窗口后,则会以它为上限发送数据,降低了网络利用率。
  3. 捎带应答
    TCP的确认应答一般会和回执数据一起回发给发送端,这样可以减少收发的数据量。
  • 点赞
  • 收藏
  • 分享
  • 文章举报
沉默舞台剧 发布了4 篇原创文章 · 获赞 2 · 访问量 264 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: