关于TCP协议的理解

TCP协议在计算机网络中的地位十分的高,也正因为如此不管是研究人员还是开发者,对TCP的理解有助于工作的提升。本文将根据自己的理解,介绍TCP协议的相关知识。

TCP是什么?

TCP(Transfer Control Protocol)传输控制协议,很明显就是五层网络结构或者ISO七层结构中的传输层协议。负责端到端的通信(这里的端指的是主机上的端口,也就是进程),是面向连接的可靠的协议(后面会分别介绍这两个方面)。当然由于是面向连接的,因此一个TCP连接只能是一对一的连接。

为什么要有TCP?

大家都知道,传输层中有两个比较有名的协议,一个是TCP,另外一个是UDP。UDP(用户数据报协议)是无连接,尽最大能力交付的协议,不太可靠,当然存在即合理,UDP可以用在一些对信息的完整性要求不太高的场景,比如视频通话等。而如何去应对可靠性需求就需要TCP协议来完成了。

为什么说TCP是面向连接的?

由于TCP协议需要保证发送方知道自己发送出去的数据是否被接收方接收,那么意味着接收方必须要给接收方一个回应,即接收方也可以发送数据,这就是TCP是全双工的原因。知道了这个之后,发送端和接收端仍然需要确认的是:发送方和接收方的发送功能和接收功能都是正常的,只有这样发送端才可以得到接收端是否接收到信息的反馈。怎么来确认呢?下面就引出了,TCP的三次握手。图引用自【码出高效】这本书。

TCP的三次握手

TCP三次握手

  • 首先是客户端发送连接请求的报文段,在该报文段头部将会设置SYN=1,表示是提出建立连接的请求,同时设置自己的一个序号为x,此时客户端进入SYN_SENT的状态。
  • 当服务器端收到连接请求之后,服务器端会发送一个确认报文段,并在头部设置SYN=1,ACK=1,同时设置自己的序号为y, 确认号字段设置为x+1(表示下一次服务器端想要接收到的报文段头部序号为x+1)。发送响应报文之后服务器端进入SYN_RCVD状态。
  • 最后客户端再次发送确认报文给服务器端,并在头部设置序号为x+1, 同时设置ACK=1,确认序号为y+1。之后进入ESTABLISHED状态。
  • 服务器端收到客户端的确认信息之后也进入ESTABLISHED状态。

这时有人会问了,为啥要三次握手两次不行么?这个是个好问题。

为啥需要三次握手而不是两次?

原因有二:
第一:信息对等
上文中已经提到,接收端和发送端都需要知道自己和对方的发送信息功能和接收信息功能是正常的。因此针对每一次握手,我们都可以用下面的表格来表示此时的状态。A表示客户端,B表示服务器端,A_A发送表示:客户端对自己的发送功能的确认信息。

  1. 第一次握手之前:
A_A发送A_A接收B_A发送B_A接收A_B发送A_B接收B_B发送B_B接收
不知不知不知不知不知不知不知不知
  1. 第一次握手之后
A_A发送A_A接收B_A发送B_A接收A_B发送A_B接收B_B发送B_B接收
不知不知正常不知不知不知不知正常
  1. 第二次握手之后
A_A发送A_A接收B_A发送B_A接收A_B发送A_B接收B_B发送B_B接收
正常正常正常不知正常正常不知正常
  1. 第三次握手之后
A_A发送A_A接收B_A发送B_A接收A_B发送A_B接收B_B发送B_B接收
正常正常正常正常正常正常正常正常

由此可见只有当第三次握手之后,双方才可以知道自己和对方的发送和接收功能是否都是正常的。
第二:防止超时
由于TCP下层的网络是不太可靠的,因此可能会出现超时的现象。比如第一次握手的信息一直在网络中迟迟传送不到服务器端,于是TCP协议启动了超时重传的机制,再次发送连接请求,经过两次握手,客户端和服务器端已经建立的连接。当数据传输完毕之后双方已经关闭了连接,此时之前在网络中的请求报文段到达了服务器端,然后服务器端又建立了一个连接,并发送响应报文给客户端,但是此时的客户端已经不是SYN_SENT的状态,就会直接丢弃响应报文。这样就会导导致服务器端出现脏连接。当脏连接过多的时候,会对系统性能产生很大的影响。

TCP的四次挥手

因为已经建立了连接,当数据传输完毕的时候,如果客户端和服务器端还一直连接这,状态不改变的话,那么如果建立很多连接之后将会对服务器端的负载等造成很大影响,因此完事了之后也要有关闭的过程,这就引出了TCP的四次挥手。同样引用来自【码出高效】的示意图。
在这里插入图片描述

  • 首先客户端会发送断开连接的请求,这这个请求中包含同步信号 SYN=1, FIN = 1, 同时附带自己的序号为u,发送完成之后客户端进入FIN_WAIT_1状态。
  • 当服务器端收到断开连接请求之后,服务器端会发送一个响应,在这个响应中包含ACK=1,SYN=1, 同时附带自己的序号v,以及期望确认号u+1,发送完成之后,服务器端传输层需要通知应用层即将关闭连接,发送剩余数据,之后进入CLOSR_WAIT状态。
  • 当客户端接收到服务器端发送回来的响应后,客户端进入FIN_WAIT_2状态。
  • 当服务器端应用层处理结束之后会同时服务器端传输层断开连接,此时发送断开连接请求,包含FIN=1, SYN= 1, 以及自己的序号w, 和确认序号 u+1(因为在发送之前还没有收到序u号u之后的报文段),发送完成之后进入LAST_ACK状态。
  • 当客户端收到来自服务器端的断开连接请求之后,会发送响应报文段其中包含的信息有:ACK=1, 序号为u+1,确认序号为 w+1,发送完毕之后,客户端需要等待两个MSL(最大段生存时间)。之后进入CLOSED状态。
  • 服务器端收到响应报文之后进入CLOSED状态。

这个时候又有小伙伴要问了,为啥需要四次握手?

为什么需要四次握手?

原因有二:

  • 第一是保证服务器端资源的释放
    在第二次挥手之后,如果没有CLOSE_WAIT阶段,如果服务器端还有数据未传送完毕,那么将可能导致一些意想不到的问题发生。同时在这段时间内,也可以释放服务器端在此连接过程中获取到的资源。
  • 第二是保证网络中不会存在本次连接的相关报文段
    在第三次挥手之后,等待2MSL的目的是使得本次连接产生的报文段在整个网络中消失。如果在这段时间内仍然收到来自服务器端的连接响应报文,客户端则会直接丢弃。同时也为了保证下一次请求的时候网络中不会有本次连接请求的报文。
  • 第三是确保被动关闭方确实关闭了
    因为有了TIME_WAIT阶段,如果第四次挥手的报文丢失了,那么当服务器端在一定时间内还没有收到来自客户端的关闭连接确认时,服务器端会重新发送关闭连接请求,客户端收到之后也会重新发送确认信息,并且重新开始计时进入TIME_WAIT阶段。

为什么说TCP是可靠的?

首先我们得明确可靠的含义:能够将数据完整的从发送端传送到接收端,并且保证在一定的时间内完成。那么第一件事就是,数据得从发送端传送到接收端,之后再考虑数据的完整性问题。为了完成这样的目标TCP主要从三个方面来考虑:

  • 流量控制
  • 拥塞控制
  • 差错控制

流量控制

  • 是什么? 流量控制,主要是通过TCP协议中的窗口来实现,这个窗口就是TCP头部中的一个字段。通过控制窗口的大小来控制发送端发送数据的快慢。

  • 为什么? 由于接收端的缓存有限,如果发送端发送的速度过快,一方面接收端如果来不及接收,就会导致数据的丢弃进而导致数据的不完整;另一方面如果网络中的数据很多,就会导致网络出现拥塞。

  • 怎么做? 首先我们想到的就是发送端每发送一个数据就等待服务器端发送一个应答过来,这样会避免上述的两个问题。但是这样的传输效率低下是另外一个问题。于是就引出了滑动窗口协议。

  • 滑动窗口协议
    这个窗口实际上就是一个循环的数组结构,通过将要发送的数据顺序放在这个数组中,从前往后发送数据,当接收到发送数据的确认报文的时候,窗口向右移动。通过该协议可以一次发送多个数据包,同时可以通过接收端发回的窗口大小来调整的发送端窗口的大小,即发送方的窗口大小要小于或者等于接收方窗口的大小,进而进行流量的控制。

拥塞控制

  • 是什么? 拥塞控制,这个和流量控制有点类似,但是其表达的是网络中的流量信息,通过控制发送端的发送窗口大小来控制拥塞。

  • 为什么? 由于网络中的数据很多,发送端发送数据速度过快就会导致网络出现拥塞,而当发送端在一定时间内没有收到应答信息时,发送端又会重新发送数据,进而加剧拥塞,因此需要通过一定的机制来控制拥塞

  • 怎么做? 在TCP协议中主要通过周而复始的循环三个步骤来进行拥塞的控制:
    1、慢开始
    在拥塞控制阶段,首先会有一个变量来表示它的拥塞窗口大小cnwd。同时也有一个阈值ssthresh来表示门限阈值。最开始cnwd从1开始首先发送第一个数据包,当发送端接收到第一个数据包的确认包之后,拥塞窗口大小会变成原来的两倍,之后再收到这两个已发送的报文的确认信息之后,拥塞窗口会再次扩大两倍,以此类推。当cnwd为ssthresh的时候将进入第二阶段即拥塞避免。
    2、拥塞避免
    当cnwd为ssthresh时,拥塞避免算法使发送端的拥塞窗口每经过一个往返时延 RTT 就增加一个 MSS 的大小。但是此时的发送方窗口大小时取决于拥塞窗口和接受方发回来的窗口大小中较小的一个,有两种情况发生:一种是当cnwd增加到某个值时,出现了网络拥塞,则ssthresh = cnwd /2, cnwd = 1,再次回到步骤1开始执行。由于接收端没接收到一个数据之后都会对之前接收到的数据进行确认,而当中间数据有丢失的时候,接收端会一直确认丢失数据之前的那个数据。当发送端收到三次同一个数据包的确认时,则会进入第三阶段即快重传。
    3、快重传
    在此阶段ssthreth = cnwd/2 ; cnwd = ssthresh; 并且立即将接收到的相同确认包的下一个数据进行快速重传。之后进入第四个阶段。
    4、快恢复
    在快恢复阶段中使用的是拥塞避免算法,此时cnwd每经过一个往返时间RTT就增加一个MSS大小。如果出现拥塞则返回到第一个阶段,如果出现重复确认则进入第三个阶段。具体图示如下:
    在这里插入图片描述

差错控制

  • 是什么? 差错控制主要是保证数据是完整的被传输到接收端。TCP协议通过伪头部将IP地址信息也加入进来进而计算校验和来验证数据的完整性。

  • 怎么做? 在TCP协议中主要通过重传机制来实现的,当发现数据的校验和不符合要求的时候,接收端会直接丢弃该数据,此时发送端会由于收不到确认包而重新发送丢失的数据包;其次是接收端在接收数据的时候通过窗口协议每次发送的确认包可以保证确认包之前的数据都是有序的,如果不是有序则会重复发送最后一个有序的数据包的确认包,也会触发快重传机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值