TCP(传输控制协议)

时间:2022-07-07 10:17:45

1、概念 
TCP是一种面向连接一对一的提供可靠交付并且是全双工基于字节流端到端传输层协议,并且具有流量控制拥塞控制以及差错控制机制

特点 
●面向连接:传输数据之前建立连接,传完数据后释放连接,通过传输控制块(TCB)保存连接信息 
●一对一:每条连接只能有两个端点,所以不能提供广播或多播服务 
●可靠交付:使用TCP协议传输的数据无差错、不丢失、不重复、按序到达 
●全双工:数据可以在两个方向上同时传输 
●字节流:应用程序和TCP之间传输的数据被表示成一串字节流 
●端到端:TCP使用端口号提供进程到进程间的通信 
●传输层:TCP协议接收应用层程序传来的数据,封装为数据报交给网络层,嵌入到IP数据报中 
●流量控制:控制发送方的发送速率,从而使接收方能够来得及接收数据 
●拥塞控制:控制发送数据量,避免网络拥塞 
●差错控制:通过校验、序号、确认号实现差错控制

TCP协议将从应用层接收到的数据封装在TCP报文中,TCP报文被封装到IP数据报中,最后风封装成数据链路层的帧

报文格式 
TCP(传输控制协议)

●源端口地址:源主机的应用程序使用的端口号 
●目的端口地址:目的主机的应用程序使用的端口号 
●序号:数据报中数据部分第一个字节的序号作为数据报的序号,共有32位,当序号达到2^32-1后,序号从零开始赋值 
●确认号:表示期望对方发送的下一个数据报的序号 
●首部字段(HLEN):数据报中首部的长度,首部长度在5到15个4字节字之间,即20到60字节 
●保留:暂时不使用 
●控制:URG代表紧急指针有效,ACK代表确认报文,PSH代表报文需要被立即发送和接收,RST代表连 接复位,SYN代表确认建立连接,FIN代表释放连接 
●窗口大小:代表源主机发送窗口大小,由接收方来确定,最大为2^16-1即65535字节 
●检验和:对报文进行校验 
●紧急指针:代表紧急数据结束的位置,只有在URG为1时才有效,紧急数据是指需要特殊处理的数据 
●选项:首部最多可以有40字节的可选信息

2、建立连接和释放连接 
TCP协议是面向连接的,需要经过建立连接、数据传输、释放连接三个阶段

TCP的各种状态

状态 说明 客户端C和服务器S
CLOSED 没有连接 C/S
LISTEN 监听状态,等待SYN S
SYN-SENT 已发送SYN,等待ACK C
SYN-RCVD 已发送SYN+ACK,等待ACK S
ESTABLISHED 连接建立 C/S
FIN-WAIT-1 第一个FIN已发送,等待ACK C
FIN-WAIT-2 第一个FIN的ACK已收到,等待第二个FIN C
CLOSE-WAIT 收到第一个FIN,已发送ACK S
TIME-WAIT 收到第二个FIN,已发送ACK,等待2MSL超时 C
LAST-ACK 已发送第二个FIN,等待ACK S
CLOSING 发出FIN后,又收到对方发来的FIN C/S

●建立连接 
连接建立过程需要三次握手,具体过程如下 
TCP(传输控制协议)

第一次握手:客户端发送SYN报文(即SYN字段置1)请求建立连接并随机设置一个序号,假设为X,虽然SYN报文并不携带数据,但仍要消耗一个序号 
第二次握手:服务器收到SYN报文后,如果同意建立连接会发送SYN+ACK报文进行确认,并为连接分配资源。确认号为X+1,表示服务器希望接收的下一个报文的序号为X+1,同时为报文随机分配一个序号,假设为Y,SYN+ACK报文不携带数据,但仍要消耗一个序号。另外,报文会定义客户端发送窗口的大小 
第三次握手:客户端收到确认报文后,再次向服务器发送ACK报文进行确认,并为连接分配资源。确认号为Y+1,代表希望接收的下一个报文的序号为Y+1,序号仍为X,因为建立连接的过程中传递的报文并未携带数据,所以序号不变。

洪泛攻击 
攻击者通过向服务器发送大量SYN报文建立连接,并伪造IP地址,服务器为连接分配资源,并等待第三次握手,在等待的过程中,服务器消耗大量资源,无法响应合法客户的请求,并且系统有可能瘫痪。通过使用Cookie,推迟资源分配,直到验证IP地址后再分配,可以减轻洪泛攻击

为什么需要三次握手? 
当连接失效的报文突然传到服务器时,如果采用两次握手,服务器发送确认建立连接报文后,便会一直等待客户端发送数据,但客户端永远都不会发送数据,造成资源浪费,如果采用三次握手,服务器没有收到客户端的确认报文,便知道客户端并未发起建立连接请求,不会等待接收数据

●数据传输 
传输过程如下 
TCP(传输控制协议) 
前三个报文既有需要传输的数据又有确认信息,但最后一个报文只有确认信息,并未携带数据,代表客户端已经发完了所有数据,并且序号和上一次发送的报文的最后一个字节的数据的序号相同

推送数据 
当有需要被立即被发送并希望服务器立即接受的紧急数据时,可以将数据报的PSH为置1。此时客户端不必等到发送窗口被填满,马上创建一个报文并立刻发送

紧急数据 
当有数据需要被应用程序特殊处理时,可以将报文中URG字段置1,紧急数据插入到报文最前边。紧急数据并不是优先被处理的数据,而是需要程序被特殊对待的数据

●释放连接 
释放连接需要经过四次挥手,具体过程如下 
TCP(传输控制协议)

第一次挥手:如果客户端向服务器发送完了数据,就会向服务器发送FIN报文,请求释放从客户端到服务器方向的连接。假设序号为X,确认号为Y 
第二次挥手:服务器在收到FIN报文后,会发送ACK报文进行确认,此时客户端到服务器的连接被释放,客户端不可以再向服务器发送数据,但可以发送ACK报文用于确认。报文的确认号为X+1,序号为Y-1,因为整个过程中服务器并未再向客户端发送数据,所以序号为Y-1 
第三次挥手:如果服务器向客户端发送完了所有数据,就会向客户端发送FIN报文,请求释放从服务器到客户端的连接,并为报文重新分配序号,假设为Z,确认号仍为X+1 
第四次挥手:客户端发送ACK报文进行确认,并进入TIME-WAIT状态,如果在2MSL时间内没有再次收到FIN报文,则关闭这条连接。MSL是报文的最长生存时间。

为什么要进入TIME-WAIT状态? 
●确保连接被释放 
如果客户端发送的ACK报文丢失,那么服务器便会认为自己发送的FIN报文丢失,便会再次发送FIN报文,如果客户端已经关闭连接,那么永远收不到FIN报文,服务器永远页收不到ACK报文,服务器无法关闭连接。如果客户端等待了2MSL长的时间,就能够保证在第一个ACK报文丢失的情况下,再次接收到服务器发送的FIN报文 
●确保新建立的连接不会接收到上一个连接中传输的数据 
假如释放了一条连接后,又马上建立了一条相同的连接(客户端IP地址与端口、服务器IP地址和端口与上一个连接相同),服务器中的程序无法分辨新建立的连接,误认为还是上一条连接,由于网络延迟,可能会接收上一个连接的数据,发生错误。如果两条连接时间相差2MSL,就能保证数据报消失

从建立连接到释放连接的整个过程 
TCP(传输控制协议)

连接复位 
当向不存在的端口建立连接时或端口并不处于LISTEN状态或当某条连接出现异常时或连接长时间处于空闲状态时,某一端可以发送RST报文拒绝连接或关闭连接。 
3、流量控制 
TCP为每个方向的数据传输设定两个窗口,分别为发送窗口和接收窗口,总共四个窗口,窗口大小时刻变化,通过使用滑动窗口协议,可以实现流量控制。窗口即不能太大也不能太小,窗口太大容易丢包,一旦丢包,需要再次发送数据,占用带宽,窗口太小需要频发传输确认数据,同样占用网络带宽

发送窗口 
发送窗口的大小受接收方以及网络拥塞程度控制,窗口中包含已经发送但未确认的数据以及待发送的数据。当发送的数据被确认后,窗口左臂根据服务器发来的报文向右移动相应大小;当接收方通知发送窗口可以变大后,发送窗口右臂向右移动。通常情况下,窗口右臂不会向左移动以收缩窗口,但是当服务器不想接收数据时,会向客户端发送rwnd=0的报文来关闭发送窗口,发送方停止发送数据。发送窗口并不是等到之前发送过的报文被确认后才发送其他报文,发送窗口可以缓存未确认的数据,如果超过指定时间未被确认则重传报文 
发送窗口如下,窗口大小为100字节 
TCP(传输控制协议)

接收窗口 
接收窗口包含希望接下来接收的数据,窗口大小总是小于等于缓存大小,因为缓存中还包含未被进程拉取的数据。当发送发送可更多数据时,接收窗口左臂向右移动,接收窗口变小;当服务器进程拉取数据后,接收窗口右臂向右移动,增大窗口。

接收窗口如下,窗口大小为100字节 
TCP(传输控制协议)

滑动窗口协议通过控制生产者生产数据和消费者消费数据的速度,实现了流量控制。流量反馈过程如下 
TCP(传输控制协议)

流量反馈过程是从接收TCP到发送TCP,从发送TCP再到发送进程,但接收进程并不能控制接收TCP的接收速度

滑动窗口协议运行过程

TCP(传输控制协议)

图中左侧部分中由上下两条黑色粗线条包裹的为发送窗口,发送窗口外左侧白色部分为已经被确认的数据,发送窗口中左侧浅灰色区域为已经发送但未被确认的数据,发送窗口汇总右侧白色区域代表将要发送的数据;图中右侧部分由两条黑色粗线条包裹的为接收窗口,接收窗口外左侧为已经确认但未被进程拉取的数据,浅灰色区域右侧的白色区域代表已经被进程拉取的数据 
注意:图中显示从客户端到服务器的单向通信,服务器对客户端的传来的数据进行确认

具体过程 
●客户端发送SYN报文,并设置序号为100,服务器接收到报文后,分配800字节缓存 
●服务器发送ACK+SYN报文,确认号为101,序号为1000,并通知发送窗口可以设为800字节 
●客户端发送ACK报文,确认号为1001,序号为100 
●客户端接收到应用层进程传递的200字节数据,并为其分配编号为101~300,并发送报文,序号为101 
●服务器向客户端发送ACK报文,窗口左臂向右移动,确认号为301,并携带接收窗口的大小为600,发送窗口接到报文后将窗口左臂向右移动窗口减小到600,虽然缓存可以容纳800字节,但接收窗口并未允许发送窗口右臂向右移动,所以减小到600 
●客户端又接收到应用层进程传递的300字节数据,向服务器发送报文,序号为301。服务器窗口缩小300字节,但由于进程拉取了100字节数据,**接收窗口右臂向右移动**100字节,服务器窗口只减少200字节 
●服务器向客户端发送ACK报文,确认号为601,并携带接收窗口的大小为400 
●服务器进程拉取200字节数据,服务器窗口为600,向客户端发送ACK报文,确认号仍为601,接收窗口大小为600

糊涂窗口问题 
当发送应用程序生产数据速度很慢或接收应用程序消耗数据速度很慢或两都有,发送方产生的报文每次只携带很少的数据,极端情况下可能只有一个字节,而TCP报文首部以及IP报文首部却有40字节,导致网络利用率很低,这种问题称作糊涂窗口

发送方产生问题的解决办法 
防止TCP报文一次一个字节的发送数据,TCP报文需等到接收到足够数据后再发送,但不能等太长时间,否则数据处理过程太慢,但也不能等太短时间,否则报文携带数据太少。Nagle算法通过权衡发送应用程序生产数据速率和网络传输数据速率,解决了模糊问题 
Nagle算法 
●发送TCP将应用程序产生的第一块数据发送给接收应用程序,即使只有一个字节的数据 
●发送TCP通过缓存累积数据并等待,直到接收到确认报文或累积到足够多数据后再发送 
●重复上一个步骤

接收方产生问题的解决办法 
假设刚开始传输时,不存在模糊问题,随着传输的进行,接收应用程序拉取缓存中的数据速度很慢,导致接收窗口很小,假设只有一个字节,从而反馈发送TCP,发送TCP接着发送只携带一个字节数据的报文,同样会导致模糊问题。可以通过Clark方法以及推迟确认来解决模糊问题 
●Clark方法 
只要有数据到达就发送确认,但在缓存足够大或至少有一半缓存空间为空之前,通知发送送接收窗口为0,发送方从而停止发送数据 
●推迟确认 
接收方直到有足够的缓存空间才对接收的报文进行确认,从而能控制发送方滑动窗口,从而停止发送数据 
4、拥塞控制 
网络中如果数据传输速度过快,超过网络容量,导致网络拥塞,那么发送方必须降低数据发送速度,减小发送窗口大小,所以网络拥塞也是影响发送窗口大小的一个因素。TCP会根据网络状况设置拥塞窗口(cwnd)的大小,发送方窗口大小=min(rwnd,cwnd)

拥塞策略 
TCP处理拥塞的策略包含三个阶段:慢开始、拥塞避免、拥塞检测。基本思想是:慢开始阶段拥塞窗口快速增长,数据传输速率快速增长,当窗口大小增长到ssthresh(慢开始门限,单位字节),进入拥塞避免阶段,等到发生拥塞时,进入拥塞检测阶段,窗口减小为为一个最大长度报文大小,再次进入慢开始阶段

●慢开始 
刚开始拥塞窗口大小为一个最大报文段长度,即cwnd=1MSS,此时只能发送一个报文段,等到第一个ACK到达后,cwnd=1+1,此时可以发送2个报文,等到收到两个ACK后,cwnd=2+2,此时可以发送4个报文,cwnd呈指数规律增长 
具体过程如下 
TCP(传输控制协议)

●拥塞避免 
在cwnd达到慢开始门限后,发送方在一个RTT(报文往返时间)时间的传输的报文数量后被确认后,拥塞窗口大小加1,窗口增长是基于RTT的,而不是基于确认报文数量 
具体过程如下 
TCP(传输控制协议)

●拥塞检测 
当网络发生拥塞,路由器会丢弃部分报文,导致发送方进行重传,此时进入拥塞检测阶段,慢开始门限减小为此时拥塞窗口大小的一半

发生超时重传 
TCP采取激进的措施:首先,把门限值降为当前窗口一半大小;其次,cwnd降为一个报文;最后,再次从慢阶段开始

发生快重传 
TCP采取温和的措施:首先,把门限值降为当前窗口一半大小;其次,cwnd设为门限值;最后,再次进入拥塞避免阶段

拥塞策略的整个过程 
TCP(传输控制协议)

5、差错控制 
TCP进行差错控制主要通过以下方法 
●检验和:通过报文的检验和字段对报文进行校验 
●序号和确认号:可以实现数据有序、不丢失、不重复传输 
●重传:差错控制的核心机制。TCP将发送过的报文保存到队列,并为其设置计时器,如果在指定时间内未收到确认,重新发送队列中序号最小的报文;如果在计时器指定时间内收到三个重复确认报文,则立即重传丢失的报文,而不用等到计时器时间到,这称为快重传 
●重排:IP数据报到达接收方可能是乱序的,TCP会对报文进行缓存,等到缺失报文到来进行重排,然后将有序报文交付给应用进程

参考 
TCP/IP协议族 
TCP/IP入门(3) –传输层 
传输控制协议 
TCP/IP State Transition Diagram (RFC793) 
【Linux网络编程笔记】TCP短连接产生大量TIME_WAIT导致无法对外建立新TCP连接的原因及解决方法—基础知识篇 
一站式学习Wireshark(五):TCP窗口与拥塞处理