TCP 协议的相关特性

文章详细介绍了TCP协议的段格式,包括源/目的端口号、序列号/确认号、标志位等,并阐述了TCP的安全和效率管控机制,如确认应答、超时重传、连接管理和滑动窗口。此外,还提到了拥塞控制、延迟应答以及异常情况下的处理,如进程终止、机器重启和网络中断。
摘要由CSDN通过智能技术生成

一、TCP协议段格式
在这里插入图片描述
(1)源/目的端口号:表示数据是从哪个进程来,到哪个进程去;
(2)32位序号/32位确认号
(3)4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15 * 4 = 60
(4)6位标志位:
URG:紧急指针是否有效
ACK:确认号是否有效
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
RST:对方要求重新建立连接;携带RST标识的称为复位报文段
SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
FIN:通知对方,本端要关闭了,称携带FIN标识的为结束报文段
(5)16位窗口大小
(6)16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光包含TCP首部,也包含TCP数据部分。
(7)16位紧急指针:标识哪部分数据是紧急数据;
(8)40字节头部选项:一个TCP报头,长度是可变的,不是像UDP一样固定8个字节,首部长度描述了TCP报头具体多长,另外选项之前的部分是固定长度(20字节),首部长度减去20字节得到的就是选项部分的长度。
二、TCP原理
TCP对数据传输提供的管控机制,主要体现在两个方面:安全和效率。
这些机制和多线程的设计原则类似:保证数据传输安全的前提下,尽可能的提高传输效率。
1.确认应答机制(安全机制)
TCP将每个字节的数据都进行了编号,即为序列号
在这里插入图片描述
每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。
2.超时重传机制(安全机制)
由于网络环境是比较复杂的,因此可能会有丢包的情况出现,虽然出现丢包的概率并不大,但在传输过程中出现丢包就会影响我们日常的网络通信,所以必须解决这一问题。一旦数据发生丢包,就要进入超时重传的机制中。
情况一:主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B,如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发。
在这里插入图片描述
情况二:主机A发送数据给B之后,数据成功到达主机B,但主机B发来的确认应答ACK丢失了,导致主机A并没有收到。 在这里插入图片描述
此时主机B会收到很多重复数据,TCP协议需要能够识别出那些包是重复的包,并且把重复的丢弃掉。这时候我们利用前面提到的序列号,就可以很容易做到去重的效果。
【注】:超时传重传是指超过一定时间还没响应就重新传输。此时间不能太长,也不能太短。如果超时时间设的太长,会影响整体的重传效率;如果超时时间设的太短,有可能会频繁发送重复的包。TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间。
3.连接管理机制(安全机制)
在正常情况下, TCP 要经过三次握手建立连接,四次挥手断开连接
在这里插入图片描述
(1)三次握手
①两个状态
LISTEN:服务器状态,表示服务器已准备就绪,随时可以有客户端来建立连接。在 Java当中,当我们创建好 ServerSocket 实例的时候,就进入了此状态。
ESTABLISHED:它表示客户端和服务器已建立连接的状态,接下来就可以进行正常通信了,在 Java 中,当我们代码中使用 accept 返回一个 Socket 对象的时候,就进入了此状态。
②关于三次握手的一些问题:
1)三次握手的功能与意义 ?
答:让通信双方各自建立对彼此的认同;验证通信双方的发送能力和接受能力是否正常;在握手的过程中双方来协商一些重要参数。
2)整个连接的过程可以进行四次握手吗 ?
答:在 B 给 A 传送的 ack + syn中,将这两步拆分来看,其实就是四次握手。本质上四次握手可以达到建立连接、确认连接的目的,但三次握手更加高效。在网络传输中,将过程拆解,就涉及到了封装与分用,因此可能会使传输的开销更大。
3)连接的过程可以只进行两次握手吗 ?
答:不行,在通信过程中无论缺少哪一环节,都无法让双方确认彼此的发送与接收状态是否完好。因此三次握手是至少的,也是连接的必须步骤。
(2)四次挥手:
三次握手表明尝试建立连接的过程,那么四次挥手就表明尝试断开连接的过程。但我们必须明确:三次握手,必须是客户端先发起请求,而四次挥手,客户端或服务器都能够发起请求,这就是客户端与服务器的特性。
①两个状态
1)CLOSE_WAIT:出现在被动发起断开连接的一方,如上图服务器 B 收到客户端 A 发来的 FIN 之后,进入的状态。此状态正在等待用户代码调用 close发方法关闭Socket,以此来发送 FIN.
2)TIME_WAIT:出现在主动发起断开连接的一方,如上图客户端 A 收到了服务器 B 发来的 FIN 之后进入的状态。此状态存在的意义主要是为了处理最后一个 ACK 丢包问题。
【注】假设客户端主动断开连接,当客户端进入TIME_WAIT状态的时候,相当于四次挥手已经完成,但为了保证客户端与服务器之间的 TCP 连接不会立即销毁,TIME_WAIT 状态仍然会存在。只有当TIME_WAIT 在等待一定的时间之后,如果仍然没有重传的 FIN 过来,才会真正销毁。这个机制用来防止最后一步的丢包问题。等待时间一般为:2 * MSL,而在 Linux 中这个 MSL 默认是1min,当然这个 MSL 可以根据程序员自己配置。
②关于四次挥手的一些问题:
为什么是四次挥手而不是三次?能进行三次挥手吗?
答:四次挥手过程中ACK 和 FIN 是分开的,在这一点上,它与三次挥手不同,这是因为四次挥手对于服务器 B 来说,ACK 和 FIN 的触发时机是不一样的。1) 当 B 收到 A 发出的 FIN 后,才回应 ACK,这个回应的步骤实际上是在系统的内核中完成的。2) 当 B 回应 ACK 之后,才发送 FIN,而发送 FIN 这个步骤实际上是通过用户代码控制的,在使用类似于 socket.close() 这样的代码时,即发送 FIN。
4.滑动窗口(效率机制)
在确认应答策略中,客户端每发送一个数据段给服务器的时候,服务器都要给一个 ACK 确认应答。当客户端收到 ACK 应答后,它就知道了服务器已经收到了刚刚的数据段,于是客户端才能再次发送下一个数据段。这样做缺点就是性能较差,效率较低。尤其是数据往返时间较长的时候,客户端可能需要等很长时间才能进行下一次发送,这就限制了同一时间段的数据传输,既然这样一发一收的方式性能较低,那么我们就一次发送多条数据,这样可以大大的提高性能。
在这里插入图片描述(1)滑动窗口特点:
① 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是4000个字节(四个段),窗口越大,则网络的吞吐率就越高;② 发送前四个段的时候,不需要等待任何ACK,直接发送;收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推。③操作系统内核为了维护这个滑动窗口,需要开辟缓冲区来记录当前还有哪些数据没有应答,只有确认应答过的数据,才能从缓冲区删掉。
下图的滑动窗口的模型为我们体现出来了多条传输与多条应答:
在这里插入图片描述
按照上图,本来主机A等待ACK是1001-5000,接下来主机B收到了2001 这个 ACK 并传回了主机A ,那么主机A 就知道了,1001 - 2000 这个数据已经被主机 B 收到了,此时主机A 也就不用继续等这个数据了,接下来就立即再发一个 5001 - 6000;此时主机 A 仍然保证窗口大小是 四个段,仍然保证当前同时等待四个段的ACK.
(2)如果出现了丢包,如何进行重传?
情况一:数据包已经抵达,接收方返回 ACK 被丢了
在这里插入图片描述
在上图中,我们可以看到主机A 在传输数据的时候没问题,但主机B 在返回 1001,3001,4001 这些 ACK 的时候,出现了丢包问题。这就导致了 主机A 在某一数据段传输之后,并不知道主机B 有没有收到刚刚的数据段。而实际上,当最终的 6001 的 ACK 在返回的过程中没有出现问题,这也就证明了 1 - 6000 的传输没有问题。这就说明不管中间过程如何应答 ACK,只要最终发送方收到应答,说明传输就没有问题。
情况二:数据包丢了
在这里插入图片描述在上图中,主机A 在传输 1001 - 2000 的数据时,发生了丢包,所以主机B 一直在尝试确认1001 这个应答。因为站在主机B 的角度看,它并没有接收到 1001 - 2000 的这些数据。然而,站在主机A 的角度看,需要一直发送数据,接下来经过三次重复的应答请求后,它就会采取重传机制,重新发送了 1001 - 2000 的数据。接着,当主机B 真正收到 1001 - 2000 的数据之后,它就准备返回 7001 的 ACK,这就说明了,1 - 7000 的数据已经正确传输,准备告诉主机A,之前的传输都已无误。那么,在刚刚的过程中,2001 - 7000 的这些数据实际上被放在了缓冲区,只有等待主机B 确认了 7001 的应答后,才会将缓冲区的数据删除掉。
5. 流量控制机制(安全机制)
接收端处理数据的速度是有限的,如果发送端发的太快,导致接收端的缓冲区被放满,这个时候如果发送端继续发送,就会造成丢包的问题,继而引起丢包重传等等一系列连锁反应。但如果发送端发的太慢,却又会使得传输数据的效率较低。因此 TCP 可以根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制。
(1)流量控制机制特点:
①接收端将接收缓冲区的剩余大小放入 TCP 首部中的 " 窗口大小 " 字段,之后,通过 ACK 通知发送端。窗口的字段越大,说明网络的吞吐量越高;窗口字段越小,传输数据的效率越低。
②接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端,此时,发送端接收到这个窗口之后,就会减慢自己的发送速度。如果接收端缓冲区满了,就会将窗口置为0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。
6. 拥塞机制(安全机制)
虽然 TCP 有了滑动窗口这个强大的传输机制,能够高效可靠地发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。因为网络上有很多的计算机正在处于交互状态,某一时刻的网络状态可能就比较拥堵。在不清楚当前的网络状态下,贸然发送大量的数据,会使传输数据变得更糟。于是就有了拥塞机制,即 TCP 先引入慢启动机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。
此处引入一个概念:拥塞窗口,发送开始的时候,定义拥塞窗口大小为 1;每次收到一个ACK 应答,拥塞窗口加1;每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为实际发送的窗口。下图为窗口的增长:
在这里插入图片描述上图拥塞窗口的增长速度,是指数级别的。" 慢启动 " 只是指初使时慢,但是增长速度非常快。为了不增长的那么快,因此不能使拥塞窗口单纯的加倍。此处引入一个叫做慢启动的阈值,当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长。如下图所示
在这里插入图片描述7. 延迟应答机制(效率机制)
延迟应答机制中表示的是:延迟接收方 ACK 的应答。
当服务器接收到数据后,不是立即返回ACK,而是稍微等会再返回,等待的时间内,接收方的应用程序就能把接收缓冲区的数据消费了,此时剩余的空间就更大了,而缓存区的剩余大小就是窗口大小。因此,要做的是在接收方能够处理的前提下,尽可能把窗口大小放大一点。
在这里插入图片描述8. 捎带应答机制(效率机制)
在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是 " 一发一收 " 的。所以,捎带应答机制就实现了将两个应答合并在一起,返回给客户端。但我们必须明确:捎带应答机制本身就是一个 " 概率性的机制 ",并不会每次都能触发。而TCP三次握手一定会合并。
在这里插入图片描述9.TCP 的粘包问题
首先我们需要明确,粘包问题中的 " 包 " ,是指的应用层的数据包。在 TCP 协议中,没有如同 UDP 一样的 " 报文长度 " 这样的字段,但 TCP 有一个序号这样的字段。站在传输层的角度,TCP 是一个一个报文传输过来的,按照序号排好序放在接收缓冲区中;站在应用层的角度,它看到的只是一串连续的字节数据。那么应用程序看到了这么一连串的字节数据,就不知道某个数据包的具体的开始位置和结束位置了。那么,这些应用层的数据包就会粘在一起,所以我们形象地把这个问题叫做粘包。
【注】 解决粘包问题的方法:
方法一:为应用层数据设定 " 分隔符或结束符 "
方法二:为应用层数据设定 " 数据长度 "
10 .TCP的异常情况
(1) 进程终止:不管进程是通过什么方式终止的,本质上都会释放内核中的 PCB,也会释放对应的文件描述符,相当于socket.close( ),此时就会触发四次挥手。但进程终止并不代表连接立即就终止,因为它还未通过四次挥手这一过程,它只是相当于关闭了文件而已。
(2) 机器重启:机器重启就是主动关闭了进程,所以异常和进程终止的情况相同。
(3) 机器掉电 / 网线断开:这是一个突发情况,机器来不及进行任何动作反应。我们再分为两种情况讨论机器掉电的情况:
情况一:掉电的是接收方
接收方一旦掉电,此时发送方还在发送数据,显然发送方不会再有接收方返回的 ACK,于是发送方就会超时重传,重传几次之后,就会通过复位报文段 RST 来尝试重置连接。而显然接收方已经断开连接了,那么最终,发送方也就会放弃这个连接,把连接资源回收。
情况二:掉电的是发送方
发送方一方掉电,此时接收方采取的策略,就是 " 心跳包 " 机制,也叫做 " 保活 " 机制。即接收方每隔一段时间,向发送发发送一个消息,确认一下对方是否还正常工作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值