TCP——传输控制协议
是计算机网络中用于提供可靠、面向连接的数据传输服务的协议。
TCP协议是传输层协议的一种,与UDP(用户数据报协议)同为传输层最重要的两种协议。TCP协议旨在确保数据在IP环境下的可靠传输,提供包括数据流传送、可靠性、有效流控、全双工操作和多路复用等服务。
TCP协议在数据传输之前,收发双方需要先建立一条逻辑通路,连接建立后才能进行数据传输,数据传输完成后需要释放连接。这种面向连接的方式确保了数据传输的可靠性。
允许通信双方的应用进程在任何时候都可以发送数据,因为两端都设有发送缓存和接受缓存。
1.发送缓存
①存放发送应用程序传输给发送方TCP准备的数据。
②存放TCP已发送但是尚未收到确认的数据。
2.接收缓存
①不按序到达的数据
②按序到达,但未被应用程序接收的数据
seq——序列号:可以理解为字节流的编号。每发送一个字节的数据,序列号+1
URG——紧急标志位(是高优先级的数据,应尽快传输,不再缓存队列中排队)
若URG置为1,代表有一部分数据需要尽快发送,紧接着启动16位紧急指针(区分紧急数据和普通数据),把紧急数据封装在所有数据的最前面
ACK——确认标志位:置为1,启动确认序号(表明数据包的用途,做回复、确认)
PSH——(紧急)推送:若置为1,应立马发送数据,不需要等缓存空间
RST——复位:TCP连接中出现错误,非正常断开连接(意外情况),就会标RST,是一个错误提示,必须释放连接,然后重新建立连接
SYN——同部位:置为1,请求建立连接
FIN——终止位:置为1,请求断开连接(表明发送方数据已完全发送,要求释放连接)
4种传输机制 确认、重传、排序、流控(滑动窗口机制)
TCP的可靠传输机制主要是靠确认应答机制来实现的,是TCP保障可靠性的核心点。确认应答就是每一次客户端向服务器发送请求之后,服务器都会返回一个请求到客户端,表示我收到了你发送过来的请求。
确认报文是唯一一种不需要被确认的数据段信息。
超时重传: 当 TCP 发出一个段后,会启动一个定时器,等待目的端确认收到这个报文段,如果不能及时收到这个确认,则触发重传机制,重发这个报文段。
由于分组在网络中传输的时间是不确定的,所以 TCP需要设置一个合适的超时时长,如果分组发送出去后这段时间内没有收到ACK,那么TCP就认为分组未送达需要重传。RTO取值应该略大于RTT,但是也不能太大。也就是在不丢包的情况下分组从发送出去到发送方收到ACK的理论时长。
由于网络中的延迟无法预料,因此RTT并非是固定数值,它是动态变化的数值,只能选择一个近似值。最后根据RTT估计值和RTT平均变化值来确定超时时长 。
超时间隔加倍机制:当连续多次未收到确认报文,设备会认为是网络拥塞过大,将重传时间加倍,因为如果按照原本的重传时间发送报文,很可能造成网络拥塞的加剧。
例如:初始超时时长为0.75秒,第一次确认超时后重传的超时时长为1.5秒,如果再次超时,则下次重传的超时时长为3秒,以此类推。这个过程一直到发送方收到新的分组为止,此时会使用测量到的来更新超时时长。
属于TCP的传输效率问题。
发送方每收到一个确认帧,发送窗口就向前滑动一个帧的位置,当发送窗口没有可以发送的帧(即发送窗口内的帧全部是已发送但未收到确认的帧)时,发送方就会停止发送,直到收到接收方发送的确认帧使窗口移动,窗口内有可以发送的帧后,才开始继续发送。
窗口的大小是接收端根据自己的缓存空间的剩余量来决定的一个动态变化的数值,那么这个剩余量就有归0的可能性。也就代表此时接收方所有缓存空间均已占用并且没能及时处理里面的资源。所以,当接收方反馈窗口值为0时,那其实就是在通知发送方,别再发送数据,处理不过来。
解决方式:客户端周期性发送窗口探测报文,该报文只包含TCP首部信息。通过触发TCP确认机制,来让服务端发送确认报文,从而告知客户端此时的窗口大小,打破死锁现象。
窗口扩大因子,只能出现在同步报文段中,否则将被忽略。
中间链路的处理能力--->拥塞控制机制
流量控制是为了让接收方能够来得及接收,而拥塞控制是为了降低整个网络的堵塞程度。
1.TCP如何判断此时网络环境出现拥塞
TCP将连接中出现的丢包行为,视为拥塞的表现。
一种是数据包确认超时。
收到来自接收方发送的三个冗余ACK报文。
2.TCP如何来控制数据的发送量
拥塞窗口--->跟接收窗口一样,都可以对发送的字节数大小进行限制。
发送方,发出未收到确认的报文的字节数,必须小于或等于拥塞窗口和接收窗口的最小值。
拥塞窗口的数值是依靠TCP拥塞控制算法得出。TCP是在保证能够支持的最大传输效率的情况下,来保证没有拥塞发生。被称为自计时。--->通过收到的确认报文来增加拥塞窗口。
拥塞控制算法--->慢启动,拥塞避免,快速恢复。
1.慢启动--->通常在开始传输数据时,拥塞窗口会被设置的很小。一般等于一个MSS数值。即一次只能发送一个数据报文段。
①每收到一个新的ACK确认报文,就会增加一倍MSS的大小。
②TCP会设定一个慢启动门限来评判。评判是否要停止慢启动的机制。
2.拥塞避免
3.快速恢复
假设,最开始传输数据时,慢启动门限为16
1、通过慢启动算法,逐步增加窗口大小
2、当窗口大小≥门限值,则切换为拥塞避免算法
3、当网络中出现拥塞情况后,因为确认报文超时而判断的拥塞--->被称为快重传
3.1、此时将慢启动门限值设定为上一次门限值的一半,此时为8
3.2、将窗口大小设定为1
4、此时重新启动慢启动算法,重复之前过程
5、如果拥塞是因为三次冗余ACK而判断--->快恢复
5.1、将慢启动门限值设定为上一次门限值的一半
5.2、将窗口大小设定为此时的门限值,直接开始使用拥塞避免算法进行扩大窗口
收到数据以后不立即返回确认报文,而是延迟一段时间。
TCP的确认应答和回执数据可以通过一个数据包进行发送。
延迟确认机制和捎带应答一般共同使用。
连接建立、数据传输、连接释放
TCP建立的双方都需要知晓对方的存在
要允许双方协议参数协商
设备可以为TCP连接分配相应资源(缓存空间)
TCP规定SYN被设置为1的报文段不能携带数据,但是要消耗一个序号。
初始序列号--->ISN:初始序列号产生是通过源地址、目的地址、源端口、目的端口和一个随机因子,通过哈希算法计算得出的。后续又加入了时间因子。
出于安全性考虑,如果被知道了初始序列号,那么很容易可以构造出一个在对方窗口内的序列号。从而伪造出TCP报文,实现TCP会话劫持。
TCP序号绕回问题
解决思路:使用时间戳选项来增加序号的有效范围。
TCP时间戳--->记录数据报文发送的时间,其中有两个字段,分别为发送方时间;回显时间。
时间戳是双向选择,需要在TCP连接建立阶段进行协商。
采用三次握手形式,不是因为两次握手无法建立连接,而是为了防止已经失效的连接请求报文突然又传送到TCP服务端,从而导致服务端回复信息,建立连接,凭空消耗资源。
当客户端发送连接建立请求报文后,因为网络阻塞,导致客户端重新发送一个连接建立请求报文, 这两个报文的序列号不同(因为为初始序列号)。
当网络阻塞减小时,可能旧的报文先到达服务端,而导致服务端回复SYN+ACK报文。此时服务端处于同步已接收状态(SYN-RCVD),但是此时对于客户端而言,服务端回复的报文是错误的报文,因为其确认序列号与客户端将要发送的报文的序列号不匹配,则客户端发送RST报文,断开连接。
当连接断开,服务端恢复到侦听状态,此时客户端发送的第二个连接请求报文到达。之后,正常建立TCP连接。
如果是两次握手,那么服务端在收到旧的SYN报文后,会直接进入到连接已建立状态。在该状态意味着已经可以发送数据,可能会存在数据传输。但是又因为此时的连接对于客户端而言时错误的,所以此时服务端传输的数据客户端不会接收。
TCP设计了一个保活计时器。
如果客户端出现故障,服务端不能一直等待下去,因为会白白浪费资源。
服务端没收到一次客户端的请求后都会复位保活计时器,一般为2小时,当保活计时器为0时,服务端主动发送探测报文,并每隔75秒发送一次。如果连续十次报文都没有接收到对端回复,则服务端认为客户端出现故障,关闭连接。