6.计算机网络-传输层

传输层

概述

在这里插入图片描述
传输层,解决端到端的通信,解决的是两个进程之间的远程网络通信问题;
在单机器中操作系统中介绍了可以使用Unix域套接字和共享内存等方式实现进程通信,这里的网络通信本质也是实现不同机器间进程之间的通信。
我们通常网络编程,直接对接的就是传输层,使用传输层的接口进行网络编程;
传输层是用户功能的最底层,却属于面向通信部分的最高层;

  • 端口
    计算机使用端口来标记不同的网络进程,端口使用16bit位表示,范围 0~65535;
    某些常用端口 FTP:21、HTTP:80、HTTPS:443、DNS:53、TelNet:23

内容概览:
UDP协议
TCP协议、TCP协议可靠传输、TCP协议流量控制、TCP协议拥塞控制、三次握手、四次释放

UDP协议详解

UDP(User Datagram Protocol)用户数据报协议,UDP是一个非常简单的协议

报文格式
源端口号(16bit)目的端口号(16bit)
UDP长度(16bit)UDP校验和(16bit)
UDP数据(长度随数据报而定)

在这里插入图片描述

特点
  • UDP是无连接协议
    UDP不需要提前建立连接,需要发送数据时立刻发送UDP数据报出去;
  • UDP不能保证可靠的交付数据
    无连接情况下直接发送,无法保证接收方是否正确接收到数据,即使数据丢失,发送方也无法知道
  • UDP是面向报文传输的
    UDP对应用层传来的数据不会做任何处理,直接封装到UDP协议的数据里发送出去
  • UDP没有拥塞控制
    UDP不关注网络状态,即使网络拥塞,UDP依然会将报文发出去。
  • UDP开销很小、速度更快
    UDP首部只有8字节,UDP发送数据报之前不会建立连接,而是直接将数据报文发出,因此速度更快

上面的UDP特点来看,原生UDP有很多缺点

  • 数据完整性不能保证
    UDP协议头部有16位校验和,但IPv4并不强制执行校验,因此无法保证报文完整性
  • 数据报无顺序
  • 丢包后无补包机制

RUDP了解一下??

UDP简介

TCP协议

TCP(Transmission Control Protocol: 传输控制协议),TCP是计算机网络中非常复杂的一个协议

TCP简述
  • TCP是面向连接的协议
  • TCP的一个连接有两端(点对点通信)
  • TCP提供可靠的传输服务
  • TCP协议提供全双工的通信
  • TCP是面向字节流的协议
    TCP会将用户报文视为一串字节流,传输时会将用户报文分成多份字节流封装成TCP报文进行发送
TCP报文
TCP报文头固定20字节源端口号(16bits)目的端口号(16bits)
序号(32)
确认号(32)
头长度(4)/单位4字节保留(3)TCP标记(9)窗口(16)
校验和(16)紧急指针(16)
可选TCP选项(可选,32bits × n),单位bytes不足部分填充(长度不定)从头长度和固定部分来看,可选部分最大为40字节
数据部分TCP报文数据

在这里插入图片描述

  • 源端口号、目的端口号
    配合IP头源IP和目的IP确定唯一的TCP连接
  • 序号
    标识TCP发送端发送的数据字节流的编号,其实就是字节流的计数

根据序号和当前数据长度能够推算出当前请求期望的下一序列,
当前序号 + 数据流长度 = 下一TCP序列号,对比上图就是1 + 1392 = 1393

  • 确认号(Ack Number)
    Ack标识为1时才有效,标识当前报文期待收到的序号,接收方返回报文时序号需和接收到报文的确认号一致。

    在这里插入图片描述

  • 头长度
    标识TCP报文头的总长度,该值也是确定数据从哪里开始,作为TCP报文数据偏移供接收端使用;头长度不定是因为可选部分长度非定长。
  • 保留字段
    预留空间,全部为0,供后TCP后续发展使用
  • 标志位(很重要)
    标志位在TCP交互中起到了非常重要的作用
标记含义
Nonce随机数??
CWR拥塞窗口减少标志,用来表明它接收到了设置 ECE 标志的 TCP 包。并且,发送方收到消息之后,通过减小发送窗口的大小来降低发送速率。
ECE用来在 TCP 三次握手时表明一个 TCP 端是具备 ECN 功能的。在数据传输过程中,它也用来表明接收到的 TCP 包的 IP 头部的 ECN 被设置为 11,即网络线路拥堵。
URG表示本报文段中发送的数据是否包含紧急数据。URG=1 时表示有紧急数据。当 URG=1 时,后面的紧急指针字段才有效。
ACK表示前面的确认号字段是否有效。ACK=1 时表示有效。只有当 ACK=1 时,前面的确认号字段才有效。TCP 规定,连接建立后,ACK 必须为 1。
PSH告诉对方收到该报文段后是否立即把数据推送给上层。如果值为 1,表示应当立即把数据提交给上层,而不是缓存起来。
RST表示是否重置连接。如果 RST=1,说明 TCP 连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。
SYN在建立连接时使用,用来同步序号。当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段;当 SYN=1,ACK=1 时,表示对方同意建立连接。SYN=1 时,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才为 1。
FIN标记数据是否发送完毕。如果 FIN=1,表示数据已经发送完成,可以释放连接。
  • 窗口大小
    16位,表示从确认号开始还可以接收多少字节的数据量,也表示当前接收端的接收窗口还有多少剩余空间。该字段可以用于 TCP 的流量控制。
  • 校验和
    用于确认传输数据是否有损坏。由伪头??、TCP头、TCP数据三部分进行计算出来。
  • 紧急指针
    16位,标识本数据段中为紧急数据的字节数(??字节数还是数据位置?),当所有紧急数据处理完后,TCP 就会告诉应用程序恢复到正常操作。即使当前窗口大小为 0,也是可以发送紧急数据的,因为紧急数据无须缓存。
  • 可选字段
    长度不定,长度是32bits的整数倍,不够长度需填充。

强烈推荐:TCP/IP协议入门教程 - 这是一组教程,共60篇文章

TCP可靠传输

该节内容摘自 http://c.biancheng.net/view/6427.html

数据分片

数据从主机传送到另一个主机往往要经过路由器、网关等设备。这些设备都要对经过的数据进行处理。由于这些设备处理数据有一定的限制,不能处理超过额定字节的数据,所以发送的时候需要确定发送数据包的最大字节数。
这个最大字节数被称为最大消息长度(Maximum Segment Size,MSS)。当要发送的数据超过该值,就需要将数据分为多个包,依次发送。该操作被称为数据分片。
MSS 是 TCP 数据包每次能够传输的最大数据量。通常,最大值为 1460 字节。如果发送的数据包大小大于 MSS 值,数据包将会被分片传输。分片原理如图所示。
在这里插入图片描述
在这里插入图片描述
其中,第 1 次和第 2 次握手包的 TCP 首部包含 MSS 选项,互相通知对方网络接口能够适应的 MSS 的大小,然后双方会使用较小的 MSS 值进行传输。

滑动窗口

在进行数据传输时,如果传输的数据比较大,就需要拆分为多个数据包进行发送。TCP 协议需要对数据进行确认后,才可以发送下一个数据包,如图所示。
在这里插入图片描述
从上图(其实就是窗口大小为1时的状态),可以看到,发送端每发送一个数据包,都需要得到接收端的确认应答以后,才可以发送下一个数据包。这样一来,就会在等待确认应答包环节浪费时间。为了避免这种情况,TCP引入了窗口概念。窗口大小指的是不需要等待确认应答包而可以继续发送数据包的最大值。

例如,窗口大小为 3,数据包的传输如图所示。
在这里插入图片描述
从上图中可以看到,发送端发送第一个数据包(1-1000),没有等待对应的确认应答包,就继续发送第二个数据包(1001-2000)和第三个包(2001-3000)。当收到第3个数据包的确认应答包时,会连续发送3个数据包(3001-4000,4001-5000,5001-6000)。当收到第6个数据包的确认应答包时,又会发送3个数据包(6001-7000,7001-8000,8001-9000)。

以这种方式发送,就可以省去多个数据包(第1、2、4、5、7、8个)的确认应答包时间,从而避免了网络的吞吐量的降低。

窗口大小指的是可以发送数据包的最大数量。在实际使用中,它可以分为两部分。第一部分表示数据包已经发送,但未得到确认应答包;第二部分表示允许发送,但未发送的数据包。在进行数据包发送时,当发送了最大数量的数据包(窗口大小数据包),有时不会同时收到这些数据包的确认应答包,而是收到部分确认应答包。

那么,此时窗口就通过滑动的方式,向后移动,确保下一次发送仍然可以发送窗口大小的数据包。这样的发送方式被称为滑动窗口机制。设置窗口大小为 3,滑动窗口机制原理如图所示。
在这里插入图片描述
上图中,每 1000 个字节表示一个数据包。发送端同时发送了 3 个数据包(2001-5000),接收端响应的确认应答包为“下一个发送4001”,表示接收端成功响应了前两个数据包,没有响应最后一个数据包。此时,最后一个数据包要保留在窗口中。

由于窗口大小为 3,发送端除了最后一个包以外,还可以继续发送下两个数据包(5001-6000 和 6001-7000)。窗口滑动到 7001 处。

数据重发

在进行数据包传输时,难免会出现数据丢失情况。这种情况一般分为两种。

  • 第一种,如果未使用滑动窗口机制,发送的数据包没有收到确认应答包,那么数据都会被重发;如果使用了滑动窗口机制,即使确认应答包丢失,也不会导致数据包重发。

    确认应答包丢失这种情况指的是前面发送的数据包没有收到对应的确认应答。当收到后面数据包的确认应答包,表示前面的数据包已经成功被接收端接收了,发送端不需要重新发送前面的数据包了。如图所示。
    在这里插入图片描述

下面分为 5 部分对上图进行讲解。

  1. 发送端第 1 次发送数据包:这里设置的窗口大小为 3,可以最大发送 3 个数据包。发送端同时发送 3 个数据包 1-1000、1001-2000 和 2001-3000。
  2. 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。数据包 1-1000 和数据包 2001-3000 的确认应答包没有丢失,但是数据包 1001-2000 的确认应答包丢失了。
  3. 发送端第 2 次发送数据包:发送端收到接收端发来的确认应答包,虽然没有收到数据包 1001-2000 的确认应答包,但是收到了数据包 2001-3000 的确认应答包。判断第一次发送的 3 个数据包都成功到达了接收端。再次发送 3 个数据包 3001-4000、4001-5000 和 5001-6000。
  4. 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。数据包 3001-4000 和数据包 4001-5000 的确认应答包丢失了,但是数据包 5001-6000 没有丢失。
  5. 发送端第 3 次发送数据包:发送端收到接收端发来的确认应答包,查看到数据包 5001-6000 收到了确认应答包。判断第 2 次发送的 3 个数据包都成功到达了接收端。再次发送 3 个数据包 6001-7000、7001-8000 和 8001-9000。
    发送数据包丢失这种情况指的是发送端发送的部分数据包没有达到接收端。那么,如果在接收端收到的数据包,不是本应该要接收的数据包,那么就会给发送端返回消息,告诉发送端自己应该接收的数据包。
  • 第二种,发送的数据包丢失,将导致数据包重发。
    如果发送端连续收到 3 次这样的数据包,就认为该数据包成功发送到接收端,这时就开始重发该数据包。如图所示。
    在这里插入图片描述

下面分为 7 部分对上图进行讲解。

  1. 发送端发送数据包:这里窗口大小为 4,发送端发送 4 个数据包,分别为 1-1000、1001-2000、2001-3000 和 3001-4000。
  2. 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。接收端收到了数据包 1-1000,返回了确认应答包;收到了数据包 1001-2000,返回了确认应答包;但是数据包 2001-3000,在发送过程中丢失了,没有成功到达接收端。数据包 3001-4000 没有丢失,成功到达了接收端,但是该数据包不是接收端应该接收的数据包,数据包 2001-3000 才是真正应该接收的数据包。因此收到数据包 3001-4000 以后,接收端第一次返回下一个应该发送 2001 的数据包的确认应答包。
  3. 发送端发送数据包:发送端仍然继续向接收端发送 4 个数据包,分别为 4001-5000、5001-6000、6001-7000 和 7001-8000。
  4. 接收端返回确认应答包:接收端接收到这些数据,并给出确认应答包。当接收端收到数据包 4001-5000 时,发现不是自己应该接收的数据包 2001-3000,第二次返回下一个应该发送 2001 的数据包的确认应答包。当接收端收到数据包 5001-6000 时,仍然发现不是自己应该接收的数据包 2001-3000,第三次返回下一个应该发送 2001 的数据包的确认应答包。以此类推直到接收完所有数据包,接收端都返回下一个应该发送 2001 的数据包的确认应答包。
  5. 发送端重发数据包:发送端连续 3 次收到接收端发来的下一个应该发送 2001 的数据包的确认应答包,认为数据包 2001-3000 丢失了,就进行重发该数据包。
  6. 接收端收到重发数据包:接收端收到重发数据包以后,查看这次是自己应该接收的数据包 2001-3000,并返回确认应答包,告诉发送端,下一个该接收 8001 的数据包了。
  7. 发送端发送数据包:发送端收到确认应答包后,继续发送窗口大小为 4 的数据包,分别为 8001-9000、9001-10000、10001-11000 和 11001-12000。

&??? 选择重传???

TCP流量控制

在使用滑动窗口机制进行数据传输时,发送方根据实际情况发送数据包,接收端接收数据包。但是,接收端处理数据包的能力是不同的。

  1. 如果窗口过小,发送端发送少量的数据包,接收端很快就处理了,并且还能处理更多的数据包。这样,当传输比较大的数据时需要不停地等待发送方,造成很大的延迟。
  2. 如果窗口过大,发送端发送大量的数据包,而接收端处理不了这么多的数据包,这样,就会堵塞链路。如果丢弃这些本应该接收的数据包,又会触发重发机制。
  3. 为了避免这种现象的发生,TCP 提供了流控制。所谓的流控制就是使用不同的窗口大小发送数据包。发送端第一次以窗口大小(该窗口大小是根据链路带宽的大小来决定的)发送数据包,接收端接收这些数据包,并返回确认应答包,告诉发送端自己下次希望收到的数据包是多少(新的窗口大小),发送端收到确认应答包以后,将以该窗口大小进行发送数据包。

TCP 流控制过程如图所示。
在这里插入图片描述

为了方便讲解,将上图以发送端发送数据包进行分隔,将其分为 3 部分进行讲解。
第一部分发送端根据当前链路带宽大小决定发送数据包的窗口大小。这里,窗口大小为 3,表示可以发送 3 个数据包。因此发送端发送了 3 个数据包,分别为 1-1000、1001-2000 和 2001-3000。
接收端接收这些数据包,但是只能处理 2 个数据包,第 3 个数据包 2001-3000 没有被处理。因此返回确认应答包,设置窗口大小为 2,告诉发送端自己现在只能处理 2 个数据包,下一次请发送 2 个数据包。

第二部分发送端接收到确认应答包,查看到接收端返回窗口大小为 2,知道接收端只处理了 2 个数据包。发过去的第 3 个数据包 2001-3000 没有被处理。这说明此时接收端只能处理 2 个数据包,第 3 个数据包还需要重新发送。
因此发送端发送 2 个数据包 2001-3000 和 3001-4000。接收端收到这两个数据包并进行了处理。此时,还是只能处理 2 个窗口,继续向发送端发送确认应答包,设置窗口为 2,告诉发送端,下一个应该接收 4001 的数据包。

第三部分发送端接收到确认应答包,查看到接收端返回窗口大小为 2。说明接收端接收了上次发送的 2 个数据包。此时仍然可以处理 2 个数据包,继续发送数据包 4001-5000 和 5001-6000。

坚持定时器

如果在接收端返回的确认应答包中,窗口设置为 0,则表示现在不能接收任何数据。这时,发送端将不会再发送数据包,只有等待接收端发送窗口更新通知才可以继续发送数据包。
如果这个更新通知在传输中丢失了,那么就可能导致无法继续通信。为了避免这样的情况发生,当接收到窗口为0的消息后会启动坚持定时器,坚持定时器每隔一段时间发送一个窗口探测报文,该包仅有1个字节,用来获取最新的窗口大小的信息。

原理如图所示:
在这里插入图片描述
下面介绍上图所示的获取窗口更新数据包的原理。

  1. 发送端发送数据。发送端以窗口大小为 2,发送了 2 个数据包,分别为 4001-5000 和 5001-6000。接收端接收到这些数据以后,缓冲区满了,无法再处理数据,于是向发送端返回确认应答包,告诉它下一个接收 6001 的数据,但是现在处理不了数据,先暂停发送数据,设置窗口大小为 0。
  2. 发送端暂停发送数据。发送端收到确认应答包,查看到下一次发送的是 6001 的数据,但窗口大小为 0,得知接收端此时无法处理数据。此时,不进行发送数据,进入等待状态。
  3. 接收端发送窗口大小更新包。当接收端处理完发送端之前发来的数据包以后,将会给发送端发送一个窗口大小更新包,告诉它,此时可以发送的数据包的数量。这里设置窗口大小为 3,表示此时可以处理 3 个数据包,但是该数据包丢失了,没有发送到发送端。
  4. 发送端发送窗口探测包。由于窗口大小更新包丢失,发送端的等待时间超过了重发超时时间。此时,发送端向接收端发送一个窗口探测包,大小为 1 字节,这里是 6001。
  5. 接收端再次发送窗口大小更新包。接收端收到发送端发来的探测包,再次发送窗口大小更新包,窗口大小为 3。
  6. 发送端发送数据。发送端接收到窗口大小更新包,查看到应该发的是 6001 的数据包,窗口大小为 3,可以发送 3 个数据包。因此发送了数据包,分别为 6001-7000、7001-8000 和 8001-9000。

TCP拥塞控制

一条数据链路经过非常多的设备,数据链路中各个部分都有可能成为网络传输的瓶颈。
对比前面介绍的流量控制,流量控制考虑的是点对点的通信量的控制,流量控制控制的是发送端发送数据的速率;而拥塞控制考虑整个网络,涉及到所有主机、路由器和所有降低网络性能的所有因素,是全局性的考虑。
拥塞控制可以防止过多数据注入到网络中,通过控制当前的窗口数来防止拥塞

&概念:
  • 接收端窗口rwnd(也称通知窗口awnd):接收端根据目前的接收缓存大小确定的信息返回的窗口值,控制
  • 拥塞窗口cwnd:发送端根据自己估计的网络阻塞状态确定的窗口值
  • 慢开始门限ssthresh:根据当前网络状态估算的一个阀值,计算合理的ssthresh值并不容易,可能会比较耗时
  • 最大消息长度MSS:单条TCP数据包不包括TCP首部的最大数据长度,三次握手syn报文中Maximum Segment Size值最小值确定(上面有介绍)
    TCP有四种拥塞控制算法:慢开始、拥塞避免、快重传、快恢复
慢开始

发送方cwnd从小值(1??)开始发送报文,当正常接收到所有ACK报文,cwnd由指数2增长,每次正常交互后以此方式增大cwnd。
当cwnd>ssthresh时,停止慢启动算法,开始使用拥塞避免算法

拥塞避免

拥塞避免算法是让cwnd缓慢增大,每次当前窗口所有报文正常交互后,cwnd按1递增;
无论是慢开始还是拥塞避免算法,只要当前网络出现拥塞,就将ssthresh设置为当前cwnd的一半但小于2,cwnd设置为1(乘法减小方式),重新使用慢开始算法,以迅速降低当前传输量,使拥塞信息有一个缓冲处理时间。

一条TCP连接有时会因为等待重传计时的超时而空闲较长时间,慢开始和拥塞避免无法解决这类问题,因此提出了快重传快恢复的拥塞控制方法。

快重传

接收方接收到一个失序报文后,后续所有响应报文都发送最后一条有序报文的确认报文,当发送方接收到3个重复的确认报文后,立刻补发一条确认报文确认号对应的数据报文给接收方,而不是要等到等待重传计时器结束触发重传。
在这里插入图片描述

快恢复

上面说到了乘法减小方式进行阻塞处理,但网络中发生丢包并不一定代表网络阻塞,这时候再从慢启动开始无疑就是增加了时间成本。
当发送方收到3个重复确认,但认为网络没有发生阻塞时,ssthresh置为当前cwnd一半,再将cwnd置为ssthresh值,这样就不在执行慢启动算法,直接直接执行拥塞避免算法,这即为快恢复

四种算法的示意图

在这里插入图片描述

网络资料:
详解TCP中的拥塞控制

TCP连接的建立(三次握手)

三次握手的过程

在这里插入图片描述

?为什么需要第三次握手

避免已失效的连接请求传至接收方,导致异常。
在这里插入图片描述

上图发送方发送第一条连接请求,长时间没收到接收方的回应,发送方重发一次连接请求。若没有第三次握手,上述情况下就会有两条连接被建立。因此才需要第三次握手才确认连接,发送方在收到第一次失效连接请求的响应后,忽略掉不发送第三次握手,这样就不会产生上述两次握手产生的问题

三次握手抓包显示

在这里插入图片描述

TCP连接的释放(四次挥手)

四次挥手的过程

在这里插入图片描述
这里引入了新的计时器:等待计时器(TIME-WAIT),对比前面介绍的的两个计时器:超时计时器坚持计时器
& 等待计时器
等待计时器一般是两倍的MSL(Max Segment Lifetime:最长报文段寿命),一般是2 × 2分钟(MSL)
等待2MSL为了确保发送方的最后ACK可以到达接收方。接收方在2MSL时间内没有收到响应,接收方会重发FIN报文,发送方再次收到FIN报文就知道了刚才的ACK没到达接收方,接着再次发送确认报文。

四次挥手抓包

??四次挥手只抓到了三个报文??
在这里插入图片描述

套接字与套接字编程

什么是套接字

前面说过,网络编程中IP和端口的组合表示的就是不同的网络进程。
这里的IP和端口的组合**{ IP : Port }我们起了一个名字称为套接字(Socket)**
Socket是抽象概念,表示TCP连接的一段,通过套接字可以进行数据的发送和接收
TCP连接由两个套接字组成:TCP = {Socket1:Socket2} = {{IP : Port }{IP : Port }}

网络套接字 VS 域套接字

网络套接字会经过整个协议栈,适用于不同机器间的信息交互;
域套接字通过域套接字文件(文件类型S)进行信息传输,适用于同一机器不同进程间的信息交互;
域套接字不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。
例:

  • client
# coding=utf-8
import socket

def client(i):

    # 创建
    s = socket.socket()

    # 连接
    s.connect(('0.0.0.0',6666))

    print('Recv msg:%s,client:%d' %(s.recv(1024),i))

    s.close()

if __name__ == '__main__':
    for i in range(10):
        client(i)
  • server
# coding=utf-8
import socket

def server():

    # 创建
    s = socket.socket()

    # 绑定
    s.bind(('0.0.0.0',6666))

    # 监听
    s.listen(5)

    # 使用
    while True:
        c,addr = s.accept()
        print('connect addr:',addr)

        ecode_data = bytes('welcome to my course, I'm sirius!'.encode(encoding='utf-8'))

        c.send(ecode_data)
        c.close()

if __name__ == '__main__':
    server()

TCP协议的四个定时器

  • 超时定时器
    超时定时器也称为超时重传定时器,主要用于TCP的可靠传输协议里面,是为了控制可能发生丢失的报文而设计的定时器,当TCP发送端发送一个报文时,就会为该报文设置一个定时器。
    如果在超时定时器结束之前收到了来自接收端的确认则撤销这个定时器;
    如果在超时定时器结束时依然没有收到接收端对该报文段的确认,则任务这个报文可能已经丢失,发送端重新发送该报文,并重新设置一个超时定时器。
    注意:发送端在超时定时器赊销前,需继续缓存未被确认的报文,直到接收端返回确认。

  • 坚持定时器
    坚持定时器用于使用滑动窗口进行流量控制。
    接收端通过调整接收窗口大小来控制发送段发送报文的速度,当接收端处缓存区已经满了时,接收端会发送一个“零窗口通知”消息。发送方收到“零窗口通知”后会进入等待状态,等待接收方发送窗口调大消息,但是这个消息是不可靠的,可能会丢失,此时若没有补救措施的话,发送方和接收方都会陷入相互等待中。
    坚持定时器就是为了解决这个问题:当发送段接收到“零窗口通知”后,会启动一个坚持定时器来周期性的主动向接收端发送查询,查询窗口是否增大。

  • 时间等待计时器
    时间等待计时器(Time-Wait)用于TCP连接关闭时能够正确关闭一个TCP’连接。
    TCP关闭需经过四次挥手(实际只抓到3个报文??),假设TCP两端为A和B,当A发起主动关闭时过程如下:
    A->FIN->B、A<-Ack<-B、A<-FIN<-B、A->Ack->B
    这个过程中,最后一次A->Ack->B是不可靠的,可能会丢失,若B没有接收到第四次挥手就不会断开连接,A若在最后一次挥手后就关闭连接,这时这个TCP连接就会是一方关闭另一方没关闭的异常状态。
    Time-Wait就用于解决这个问题:当A发送出最后一次挥手后,就会启动2倍MSL(两倍最大报文段寿命)时间的计时器,2MSL是为了确保B能接收到A的最后一次挥手。假设A的最后一次确认报文传输过程中丢失了,B没收到确认会触发超时定时而重新发送FIN报文,A收到FIN后会重新发送Ack重启Time-Wait,2MSL就是为了留下这段确认的最大时间。

  • 保活计时器
    保活计时器是用于保活TCP连接而设计的,一般用于服务端。
    假设连接双方在建立连接传了一段数据,然后都保持静默了,双方也都没有关闭连接,这时若其中一方发生故障,另一方无法发现,那么这个连接将会永远被打开。
    保活计时器用于解决这个问题:服务端一般都会设置一个保活定时器,每次收到对方的数据会重置这个定时器,若果定时器超时,服务端则会发送探测报文,探测客户端是否在线,如果没有收到响应的话,则认为客户端已经断开连接,服务端也会终止这个连接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hzw@sirius

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值