面试必备之TCP知识

概述

关于TCP的杂乱知识点,不成体系,毕竟TCP真的太复杂。

TCP,Transmission Control Protocol;IP,Internet Protocol,两者共同组成TCP/IP协议族,包含一系列构成互联网基础的网络协议。

OSI七层网络模型

面试必备之TCP知识
图片来自于OSI七层网络模型

OSI七层由于太过严格,所以并没有应用在计算机中,其衍生的TCP/IP四层模型,被广大操作系统所应用。

TCP/IP四层网络模型

将ISO七层加以精简,变成四层:链路层、网络层、传输层和应用层。

按照层次由上到下,层层包装。最上面是应用层,有HTTP、FTP等协议。第二层是传输层,包括TCP和UDP协议。第三层是网络层,IP协议,负责对数据加上IP地址和其他的数据以确定传输的目标。第四层是数据链路层,这个层次为待传送的数据加入一个以太网协议头,并进行CRC编码,为最后的数据传输做准备。

TCP/IP协议通信的过程其实就对应着数据入栈与出栈的过程。入栈的过程,数据发送方每层不断地封装首部与尾部,添加一些传输的信息,确保能传输到目的地。出栈的过程,数据接收方每层不断地拆除首部与尾部,得到最终传输的数据。

长连接

连接是指网络传输层的使用TCP协议经过三次握手建立的连接。

长连接是指建立的连接长期保持,不管此时有无数据包的发送。

短连接是指双方有数据发送时,就建立连接,发送几次请求后,就主动或被动断开连接。

心跳,用来检测系统是否存活或网络链路是否通畅的一种方式,其一般做法是定时向被检测系统发送心跳包,被检测系统收到心跳包进行回复,收到回复说明对方存活。
心跳能够给长连接提供保活功能,能够检测长连接是否正常;如果多次(一般三次)检测不到心跳则认为已断开连接,此时需要做后续的措施,如下线,重新选举等。

长连接和心跳的意义:

减少连接建立过程的耗时:TCP连接建立需要三次握手,也就说需要三次交互才能建立一个连接通道,尤其在异地容灾机器部署情况下优势更明显。
方便实现push数据:数据交互-推模式实现的前提是网络长连接,有了长连接,连接两端很方便的互相push数据,来进行交互。

与UDP区别

UDP:面向无连接,不可靠协议,不建立连接,没有超时重发,速度快,不保证次序;传输数据时,有大小限制,数据报必须限定在64KB之内;不需要连接,数据包括目的端口号和源端口号信息,可实现广播发送。

常用于:视频会议系统,直播,DNS解析。

状态转换

面试必备之TCP知识

可靠性

可靠的定义:发送方发送的数据到达接收方时不会发生错误,不会丢失,不会乱序。

TCP通过下列方式来提供可靠性:

将数据截断为合理的长度:应用数据被分割成TCP认为最适合发送的数据块。这和UDP完全不同,应用程序产生的数据报长度将保持不变;
超时重发:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段;
确认:当TCP收到发自TCP连接另一端的数据,它将发送一个确认,不是立即发送,通常将推迟几分之一秒。(之所以推迟,可能是要对包做完整校验)
TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。 (校验出包有错,丢弃报文段,不给出响应,TCP发送数据端,超时时会重发数据)
既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。 (对失序数据进行重新排序,然后才交给应用层)
去重:既然IP数据报会发生重复,TCP的接收端必须丢弃重复的数据;
流量控制:TCP连接的每一方都有固定大小的缓冲空间,接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。TCP使用的流量控制协议是可变大小的滑动窗口协议。

有序

三次握手

ACK,SYN,FIN,SEQ

TCP是一个可靠的协议,它能保证接收方能够完整正确地接收到发送方发送的全部数据。

第一次握手:客户端发送SYN包(SYN=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手;

四次挥手

面试必备之TCP知识

第一次分手: 主机1(可以使客户端,也可以是服务器端),设置Sequence Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
第二次分手: 主机2收到主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;
第三次分手: 主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;
第四次分手: 主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接。

MSL:Maximum Segment Lifetime,报文段最大生存时间,它是任何报文段被丢弃前在网络内的最长时间。

为什么要等待2MSL?

保证TCP协议的全双工连接能够可靠关闭
保证这次连接的重复数据段从网络中消失

第一点:如果主机1直接CLOSED,那么由于IP协议的不可靠性或者是其它网络原因,导致主机2没有收到主机1最后回复的ACK。那么主机2就会在超时之后继续发送FIN,此时由于主机1已经CLOSED,就找不到与重发的FIN对应的连接。所以,主机1不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。

第二点:如果主机1直接CLOSED,然后又再向主机2发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达主机2,由于新连接和老连接的端口号是一样的,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。

N层交换技术

二层交换

交换原理:根据第二层数据链路层的MAC地址来实现端到端的数据交换;
工作流程:

交换机某端口收到数据包,读取源MAC地址,得到源MAC地址机器所连端口;
读取目的MAC地址,在地址表中查找对应端口;
如果地址表中有目的MAC地址对应端口,直接复制数据至此端口;
如果地址表中没有目的MAC地址对应端口,广播所有端口,当目的机器回应时,更新地址表,下次就不需要广播;

不断的循环上述过程,全网的MAC地址信息都可以学习到,二层交换机就这样学习和维护它的地址表。第二层交换机根据MAC选择端口转发数据,算法简单,可采用廉价芯片实现且速度快。

三层交换

交换原理:根据第三层网络层的IP地址来完成端到端的数据交换;场景:A(ip1) => 三层交换机 =>B(ip2)

工作流程:

A发数据给B,根据B的ip地址+子网掩码,A能够判断出B和自己是否在同一个网段;
如果在同一个网段内,但A不知道B的MAC地址,A会发送一个ARP请求,以获取B的MAC地址,并根据MAC通过二层交换机将数据发送给B;
如果不在同一个网段内,且不知道B的MAC地址,A会将数据包发送给网关(A的本地一定有网关的MAC地址)。网关收到数据包后,将源MAC地址会修改为网关自己的MAC地址,目的IP对应的MAC地址为目的MAC地址,以完成数据交换。

数据通过第三层转发设备后,会记录IP与MAC的映射关系,下次需要转发时,不会再经过第三层设备。

四层交换

二层和三层交换设备都是基于端到端的交换,这种基于IP和MAC地址的交换技术,传输率高效,但是缺乏根据目的主机应用需求动态交换数据的功能。

四层设备不但能够完成端到端的交换,还能够根据目的主机的应用特点,分配或限制其流量;四层设备基于传输层数据包交换,是一类建立在TCP/IP应用层之上,实现用户应用需求的设备;它实现一类应用层的访问控制与质量保证服务,与其说它是硬件设备,不如说它是软件网络管理系统。

四层交换核心技术

包过滤利用四层信息定义过滤规则,能够控制指定端口的TCP/UDP通信,它可以在高速芯片中实现,极大提高包过滤速率;
包优先级三层以下设备只有MAC,PORT,IP等信息,因为缺乏四层信息,无法确认TCP/IP等四层优先级信息;四层设备允许基于目的地址/端口(即应用服务)的组合来区分优先级。
负载均衡将附加有负载均衡服务的IP地址,通过不同的物理服务做成一个集群,提供相同的服务,并将其定义为一个单独的虚拟服务器;这个虚拟服务器是一个有独立IP的逻辑服务器,用户数据流只需要流向虚拟服务器IP,而不与物理服务器进行通信;只有通过交换机执行网络地址转换(NAT)后,才能得到真实访问;虚拟服务器组里转换通信流量实现均衡,其中具体关系到OSPF、RIP、VRRP等协议;
主机备用连接同(3)所含技术类似,可以实现主备同IP自动切换;

七层交换

交换原理:比四层更进一步,可以根据应用层的数据报文来完成更多的复杂交换功能(如根据http报文路由),七层交换还没有具体的标准。

流量控制

TCP协议有两个比较重要的控制算法:流量控制,阻塞控制。TCP协议通过滑动窗口来进行流量控制,它是控制发送方的发送速度从而使接受者来得及接收并处理。

滑动窗口本质上是为了在通信过程中同步收发双方的速率。通过发送端的发送窗口和接收端的接收窗口来保证发送的可靠性,同时协调发送的速度。
面试必备之TCP知识
对于发送端来说,整个窗口分为下面四段,一是已经发送也收到确认回复的;二是已经发送但尚未收到回复的;三是还没有发送但即将发送的(接收方有空间,只是发送方尚未发送而已);四是没发送,但是接收方已经没空间的

对于接收方来说,整个窗口分为三段,一是已经接收并且已经回复ACK的;二是已经接收的;三是为接收也没准备接收的
而所谓的滑动,则是将窗口从上一次收到的连续ACK的位置整个划到下一次收到连续ACK的位置而已。不连续则不能算作已经接收完毕。

拥塞控制

拥塞控制作用于整体网络,它是防止过多的包被发送到网络中,避免出现网络负载过大,网络拥塞的情况。
Congestion Control State Machine
和TCP一样,拥塞控制算法也有其状态机。当发送方收到一个ACK时,Linux TCP通过状态机的状态来决定其接下来的行为,是应该降低拥塞窗口cwnd大小,或保持cwnd不变,还是继续增加cwnd。如果处理不当,可能会导致丢包或者超时。
面试必备之TCP知识
五种状态:

Open状态
Open状态是拥塞控制状态机的默认状态。这种状态下,当ACK到达时,发送方根据拥塞窗口cwnd(Congestion Window)是小于还是大于慢启动阈值ssthresh(slow start threshold),来按照慢启动或者拥塞避免算法来调整拥塞窗口。
Disorder状态
当发送方检测到DACK(重复确认)或者SACK(选择性确认)时,状态机将转变为Disorder状态。在此状态下,发送方遵循飞行(in-flight)包守恒原则,即一个新包只有在一个老包离开网络后才发送,也就是发送方收到老包的ACK后,才会再发送一个新包。
CWR状态
发送方接收到一个显示拥塞通知时,并不会立刻减少拥塞窗口cwnd,而是每收到两个ACK就减少一个段,直到窗口的大小减半为止。当cwnd正在减小并且网络中有没有重传包时,这个状态就叫CWR(Congestion Window Reduced,拥塞窗口减少)状态。CWR状态可以转变成Recovery或者Loss状态。
Recovery状态
当发送方接收到足够(推荐为三个)的DACK(重复确认)后,进入该状态。在该状态下,拥塞窗口cnwd每收到两个ACK就减少一个段(segment),直到cwnd等于慢启动阈值ssthresh,也就是刚进入Recover状态时cwnd的一半大小。发送方保持Recovery状态直到所有进入Recovery状态时正在发送的数据段都成功地被确认,然后发送方恢复成Open状态,重传超时有可能中断Recovery状态,进入Loss状态。
Loss状态
当一个RTO(重传超时时间)到期后,发送方进入Loss状态。所有正在发送的数据标记为丢失,拥塞窗口cwnd设置为一个段(segment),发送方再次以慢启动算法增大拥塞窗口cwnd。

Loss和Recovery状态的区别是:Loss状态下,拥塞窗口在发送方设置为一个段后增大,而 Recovery状态下,拥塞窗口只能被减小。Loss状态不能被其他的状态中断,因此,发送方只有在所有Loss开始时正在传输的数据都得到成功确认后,才能退到Open状态。

面试必备之TCP知识
四个算法:慢启动,拥塞避免,拥塞发生时算法和快速恢复

慢启动算法 – Slow Start
所谓慢启动,也就是TCP连接刚建立,一点一点地提速,试探一下网络的承受能力,以免直接扰乱网络通道的秩序。
慢启动算法:

连接建好的开始先初始化拥塞窗口cwnd大小为1,表明可以传一个MSS大小的数据
每当收到一个ACK,cwnd大小加一,呈线性上升
每当过一个往返延迟时间RTT(Round-Trip Time),cwnd大小直接翻倍,乘以2,呈指数让升
ssthresh,是一个上限,当cwnd >= ssthresh时,即进入拥塞避免算法

拥塞避免算法 – Congestion Avoidance
当拥塞窗口大小cwnd大于等于慢启动阈值ssthresh后,就进入拥塞避免算法:

收到一个ACK,则cwnd = cwnd + 1 / cwnd
每当过了一个往返延迟时间RTT,cwnd大小加一
过了慢启动阈值后,拥塞避免算法可以避免窗口增长过快导致窗口拥塞,而是缓慢的增加调整到网络的最佳值。

拥塞状态时的算法
一般来说,TCP拥塞控制默认认为网络丢包是由于网络拥塞导致的,所以一般的TCP拥塞控制算法以丢包为网络进入拥塞状态的信号。对于丢包有两种判定方式,超时重传RTO[Retransmission Timeout]超时,和收到三个重复确认ACK。
超时重传是TCP协议保证数据可靠性的一个重要机制,其原理是在发送一个数据以后就开启一个计时器,在一定时间内如果没有得到发送数据报的ACK报文,那么就重新发送数据,直到发送成功为止。
但是如果发送端接收到3个以上的重复ACK,TCP就意识到数据发生丢失,需要重传。这个机制不需要等到重传定时器超时,所以叫做快速重传,而快速重传后没有使用慢启动算法,而是拥塞避免算法,所以这又叫做快速恢复算法。
超时重传RTO[Retransmission Timeout]超时,TCP会重传数据包。TCP认为这种情况比较糟糕,反应也比较强烈:
由于发生丢包,将慢启动阈值ssthresh设置为当前cwnd的一半,即ssthresh = cwnd / 2
cwnd重置为1
进入慢启动过程

最为早期的TCP Tahoe算法就使用上述处理办法,但是由于一丢包就一切重来,导致cwnd重置为1,十分不利于网络数据的稳定传递。TCP Reno算法进行优化,当收到三个重复确认ACK时,TCP开启快速重传Fast Retransmit算法,而不用等到RTO超时再进行重传:

cwnd大小缩小为当前的一半
ssthresh设置为缩小后的cwnd大小
然后进入快速恢复算法Fast Recovery
面试必备之TCP知识
快速恢复算法
TCP Tahoe是早期的算法,所以没有快速恢复算法,而Reno算法有。在进入快速恢复之前,cwnd和ssthresh已经被更改为原有cwnd的一半。快速恢复算法的逻辑如下:

cwnd = cwnd + 3 * MSS,收到3个重复的ACK
重传DACKs指定的数据包
如果再收到DACKs,那么cwnd大小增加一
如果收到新的ACK,表明重传的包成功,那么退出快速恢复算法。将cwnd设置为ssthresh,然后进入拥塞避免算法

面试必备之TCP知识
第五个包发生丢失,所以导致接收方接收到三次重复ACK,也就是ACK5。所以将ssthresh设置为当时cwnd的一半,也就是6/2 = 3,cwnd设置为3 + 3 = 6。然后重传第五个包。当收到新的ACK时,也就是ACK11,则退出快速恢复阶段,将cwnd重新设置为当前的ssthresh,也就是3,然后进入拥塞避免算法阶段。

慢启动

拥塞避免

拥塞发生时算法

快速恢复

Fast Recovery,

TCP攻击

TCP攻击有:

SYN攻击:主要是建联时攻击。攻击方发起SYN请求,被攻击方收到请求后回应ACK,此时攻击方本应当回应此ACK使得被攻击方变为establish状态,然而攻击方此时不做回应,使得被攻击方维护的未连接队列中该记录存活时间因为超时重试而增加,而短期大量该类型攻击淹没可使得被攻击方未连接队列不断增长,让系统响应变慢,网络拥堵甚至系统崩溃
RST攻击:RST复位主要是通信任何一方认为异常的连接则可以清除该连接的缓冲区,并向对方发送RST标志强制关闭连接。RST攻击主要是用来断一个已有连接的,比如A与B连接中,此时C冒出来伪装成A向B发送一个带RST位的请求,则B将清除所有与A的记忆,下次A再来时,B将不认识A;如果C冒充A向B发送一个SYN请求,则B会主动发起RST复位。这类攻击主要用来瘫痪重要连接,从而趁虚而入。

其他

谷歌的BBR

TCP优化

TCP连接复用

TCP Connection Reuse
一般情况下,客户端在发送HTTP请求之前需要先与服务器进行TCP三次握手,建立TCP连接,然后发送HTTP请求。服务器收到HTTP请求后进行处理,并将处理的结果发送回客户端,然后客户端和服务器互相发送FIN并在收到FIN的ACK确认后关闭连接。在这种方式下,一个简单的HTTP请求需要十几个TCP数据包才能处理完成。

TCP连接复用技术通过将前端多个客户的HTTP请求复用到后端与服务器建立的一个TCP连接上。这种技术能够大大减小服务器的性能负载,减少与服务器之间新建TCP连接所带来的延时,并最大限度的降低客户端对后端服务器的并发连接数请求,减少服务器的资源占用。

采用TCP连接复用技术后,Client A与负载均衡设备之间进行三次握手并发送HTTP请求。负载均衡设备收到请求后,会检测服务器是否存在空闲的长连接,如果不存在,服务器将建立一个新连接。当HTTP请求响应完成后,客户端则与负载均衡设备协商关闭连接,而负载均衡则保持与服务器之间的这个连接。当有其它客户端(Client B)需要发送HTTP请求时,负载均衡设备会直接向与服务器之间保持的这个空闲连接发送HTTP请求,避免新建TCP连接造成的延时和服务器资源耗费。

面试必备之TCP知识
在HTTP1.0中,客户端的每一个HTTP请求都必须通过独立的TCP连接进行处理,而在HTTP 1.1中,对这种方式进行改进。客户端可以在一个TCP连接中发送多个HTTP请求,这种技术叫做HTTP复用(HTTP Multiplexing)。TCP连接复用是将多个客户端的HTTP请求复用到一个服务器端TCP连接上,HTTP复用则是一个客户端的多个HTTP请求通过一个TCP连接进行处理。前者是负载均衡设备的独特功能;而后者是HTTP 1.1协议所支持的新功能,目前被大多数浏览器所支持。

有些用户和厂商喜欢采用连接复用率来评判一个负载均衡设备的TCP连接复用技术的好坏。一般来说,TCP连接复用率是指一段时间内负载均衡设备成功处理的客户端HTTP请求总数与这段时间负载均衡与服务器之间建立的TCP连接总数的比值。但是,TCP连接复用率和应用的特点、服务器设置、计算周期以及请求的发送模式等也有很大的关系,不同的应用环境下计算出来的TCP连接复用率会有很大的差异。其实,连接复用效率的关键在于负载均衡设备是否能够及时释放已经空闲的服务器端连接。有些厂商采用发送HTTP响应后等待一定时间,如果这段时间内无数据传输即释放该连接。而等待时间往往是秒级的,对于数据往返时间的毫秒级,其复用效果明显不会很好。最为有效的连接复用技术是在负载均衡设备给客户端发送HTTP响应之后,收到客户端确认ACK数据包即释放该连接。这种方式避免任何额外的等待时间,理论上没有更高效的复用方法。

TCP缓冲机制

TCP缓冲是为了解决后端服务器网速与客户的前端网络速度不匹配而造成服务器资源浪费的问题。由于服务器与负载均衡设备之间的网络带宽速率高,时延小,通过将服务器端的请求缓冲在负载均衡设备的缓冲区中,防止由于客户端缓慢的网络链路和较高的时延造成服务器端连接阻塞问题。

通过采用TCP缓冲技术,可以提高服务器端响应时间和处理效率,减少由于通信链路问题给服务器造成的连接负担。另外,由负载均衡设备来处理网络阻塞造成的数据包重传,使每个客户端的流量得到最佳的控制。
面试必备之TCP知识
客户端与负载均衡之间采用的链路具有较高的时延和较低的带宽,而负载均衡与服务器之间采用时延较低和高带宽的局域网连接。

负载均衡收到客户端发来的HTTP请求并将其转发给后端的服务器进行处理;
服务器对请求进行处理后,将响应的内容依次返回负载均衡设备,负载均衡设备收到响应的数据包后,会将数据包依次缓存在缓冲区中,服务器的响应速度将依据负载均衡和服务器之间的链路质量;
当负载均衡上缓存第一个响应的数据包后,负载均衡将响应的数据包按次序返回给客户端,此时,响应的速度将依赖于负载均衡与客户端之间的链路质量;
当响应内容数据包依次传送给客户端并收到客户端的ACK确认请求后,负载均衡将缓冲区资源释放出来为其它TCP连接使用。

TCP缓冲技术是L7应用负载均衡的核心,它将服务器与客户端之间的TCP连接分成两个独立的TCP连接,并分别进行处理,以适应两边不同的网络环境。此外通过TCP缓冲技术,将客户端的HTTP请求完整的接收下来并进行分析,还可以提供一些高级负载均衡的应用功能,如:URL-Hashing,URL交换(URL-Switching),基于Cookie或会话的连接保持(Cookie/Session Persistence)等等。

参考

OSI七层网络模型
TCP拥塞控制算法简介
TCP之三次握手四次挥手
长连接和心跳的那些事儿

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...