TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输层协议,用于在网络上可靠地传输数据。
TCP协议的特点:
- 面向连接:在通信开始之前,发送方和接收方需要建立一个连接,双方通过这个连接来进行数据的传输和通信(连接的建立和关闭采用三次握手和四次挥手);
- 可靠性:TCP协议提供了可靠的数据传输,通过序号、确认、重传和超时机制等,确保数据能够按照正确的顺序、无损的传输到接收方并提供可靠的确认机制;
- 流量控制:TCP协议使用滑动窗口机制来控制发送方与接收方的数据传输速度,确保接收方能够及时处理接收到的数据而不会发生数据溢出;
- 拥塞控制:TCP协议使用拥塞窗口和慢启动等机制来控制数据的发送速度,避免网络拥塞并提高网络的利用率,以保证数据的可靠传输;
- 数据分段和重组:TCP协议将应用层传输的较大的数据分割成较小的数据段,并在接收方将这些数据段重新组装成完整的数据,这样来适应不同的网络传输环境和MTU限制。
MTU限制(Maximum Transmission Unit):
MTU限制指的是在数据传输过程中,网络设备和网络协议所支持的最大数据包的大小。
- MTU指的是在网络通信中每个数据包的最大传输大小,在网络通信中的数据包是通过分组传输的,每个数据包都有自己的头部信息和有效负荷(payload),而MTU限制表示在一个网络链路中数据包的最大容量,包括数据的头部信息和有效负荷,对于超过MTU限制的数据包需要进行分片,即将其拆分为小于MTU限制的几个片段,在进行传输;
- MTU限制是由网络设备和网络协议所共同决定的,在不同的网络设备和协议中,MTU限制可能有所不同,例如:在以太网中MTU限制通常为1500字节;在拨号连接或者某些无线网络中MTU限制可能较小;
- MTU限制对数据传输会产生一定的影响,如果数据包超过了网络链路的MTU限制,那么它就需要进行分片,会增加网络传输的开销和延迟。同时在经过网络设备时,如果某个路由器或设备的MTU限制小于数据包的大小,那么该数据包可能会被丢弃或者需要进一步处理。
TCP协议的内部机制:
1. 序号和确认机制:(主要体现在三次握手和四次挥手的过程中)
- 序号机制:发送方在发送数据时,为每个数据包分配一个唯一的标识序号,序号是一个32位的字段,用于标识发送方发送的字节流的顺序。初始的序号是随机选择的,之后没法送一个字节的数据,序号就增加1;发送方将序号添加到每个数据包的报头中,接收方在收到数据包后,利用序号来重新组装和重组数据;
- 确认机制:接收方在收到数据包后,会给发送方发送一个确认(ACK)消息,告知发送方已经成功接收到数据。ACK也是一个32位的字段,表示接收到序号为ACK-1的数据,ACK是积累确认,即接收方只发送最新收到的数据包的序号,而不是每个接收到的数据包单独进行确认。
2. 超时重传、快速重传和快速恢复机制:
- 超时重传机制:当发送方发送数据包后,会启动一个定时器。如果在规定的时间内没有收到该数据包的确认消息(ACK),发送方则会认为数据包已经丢失,会进行超时重传,发送方会重新发送丢失的数据包直到收到对应的应答消息;
- 快速重传机制:快速重传是一种提起发送重复ACK消息的机制,当接收方收到一个失序的数据包时,会发送一个重复的ACK消息给发送方,告知发送方已经收到了这个失序的数据包,如果发送方连续收到是三个重复的ACK消息,它就会任务接收方正在等待这个失序的数据包,而不是一个普通的重复ACK消息,此时就会立即重传对应的数据包不需要等待超时时间到达;
- 快速恢复机制:在进行快速重传后,发送方会进入快速恢复状态,在该状态下,发送方会将拥塞窗口减半,并根据接收到的新的ACK逐渐增加拥塞窗口的大小,这样可以控制拥塞并逐渐恢复到之前的传输速率。
3. 心跳检测机制:
- TCP心跳检测是一种用于检测tcp连接是否仍然有效的机制,它主要用于长时间没有数据交互的情况下来保持TCP连接的活跃性和稳定性。当tcp连接处于空闲状态时,既没有发生任何数据交互,可能会面临一些问题,如:网络中间设备的超时设置、防火墙会话超时等,为避免这些问题可以使用心跳检测机制;
- 发送方定期(固定的时间间隔,通常为几秒钟)向接收方发送心跳数据包(也称Keep-Alive数据包),它是一个空的TCP数据段,没有实际的数据内容,接收方在收到心跳数据包时,必须发送一个ACK确认消息作为回应,告知发送方连接没有断开仍然活跃;如果发送方在一定时间内没有收到对方的ACK消息,则可以认为连接已经断开或发生异常,发送方可以采取进一步措施,如:尝试重连、关闭连接或通知应用程序等。
4. 滑动窗口机制:
- TCP滑动窗口是用于控制流量和拥塞控制的重要机制,它允许发送方和接收方在数据传输过程中动态的调整发送和接收数据的速率。滑动窗口是通过维护发送方和接收方之间的窗口来实现的,窗口指的是发送方可以连续发送的字节范围或接收方可以接收的字节范围,它们各自维护一个窗口用于控制数据流动;
- 发送方首先发送一个固定大小的窗口(发送窗口),表示发送方可以发送的字节数,接收方接收到数据后,将数据放入接收缓冲区中,并发送一个确认消息ACK表示接收方可以接收的字节数,发送方收到应答消息后,会对发送窗口进行滑动,即将窗口向右移动,表示发送方已经成功发送了一部分数据发送方可以根据接收方的ACK消息调整发送窗口的大小。如果接收方的接收缓冲区还有空间,发送方可以增大发送窗口的大小,以加快发送速度。反之,如果接收方的接收缓冲区已满,发送方需要减小发送窗口的大小,以避免数据丢失和网络拥塞。接收方收到数据后,会将数据从接收缓冲区中移出,以释放空间接收新的数据。
5. 慢启动和拥塞控制机制:
- 慢启动机制:在TCP连接刚建立时,发送方的发送窗口较小,为了快速确定网络的拥塞情况,发送方会以指数增长的方式(2倍)增加发送窗口的大小。发送方每发送一个段的数据,即每收到一个ACK消息,发送窗口的大小就会增加一倍。这样,发送方的发送速率可以快速增长,直到网络发生拥塞或达到一个阈值(拥塞窗口大小)为止。
- 拥塞控制机制:当网络发生拥塞时,发送方会通过检测重复的ACK消息或者超时定时器的触发来判断拥塞的发生。一旦发生拥塞,发送方会将发送窗口减半,并将阈值降低到当前拥塞窗口的一半(拥塞避免阈值)。发送方在进入拥塞避免状态后,发送窗口的大小逐渐增加,不再以指数增长,而是以线性增长的方式(每收到一个ACK消息增加一个MSS)增加。发送方每收到一个ACK消息,发送窗口的大小增加一个分组大小。如果再次发生拥塞,发送方会继续减半发送窗口,并将阈值降低到当前拥塞窗口的一半。在拥塞避免状态下,发送方会持续增加拥塞窗口的大小,直到达到网络的承载能力。
- TCP慢启动和拥塞控制机制是TCP协议中用于控制数据传输速率和避免网络拥塞的重要机制。它通过适应网络环境的变化,避免过快发送数据而导致网络拥塞,从而保证数据传输的可靠性和稳定性。通过慢启动和拥塞控制机制,TCP可以根据网络的拥塞程度和接收方的接收能力来动态调整数据的发送速率,从而避免网络拥塞和丢包。这样就可以保证数据传输的可靠性和稳定性,同时也保护了整个网络的正常运行。
↓↓↓最重要的部分来喽~~~
TCP协议建立连接和释放连接的过程(三次握手和四次挥手):
TCP三次握手的过程:
在建立连接之前主动打开连接的客户端结束CLOSED阶段,被动打开的服务器端也结束CLOSED阶段,并进入LISTEN阶段,随后开始进行“三次握手”。
第一次握手:首先客户端先向服务器端发送一个TCP报文
- 标记位为SYN,表示“请求建立新连接”;
- 序号为Seq=X(X一般为1)(传输信息的时候每个数据包的序号);
- 随后客户端进入SYN-SENT阶段(请求连接的阶段)。
第二次握手:服务器端收到来自客户端的TCP报文之后,结束LISTEN阶段。并返回一段报文
- 标志位为SYN和ACK,表示确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接(即告诉客户端,服务器收到了数据);
- 序号为Seq=y;(返回一个收到信息的数据包 并给其标序号为y)
- 确认号为Ack=x+1,表示收到客户端的序号Seq并将其值加1作为自己确认号Ack的值(两端配对 接收到消息 并反馈的过程;随后服务器端进入SYN-RCVD阶段。
- ACK:代表确认收到消息
第三次握手:客户端接收到来自服务器确认收到数据的TCP报文后,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段,并返回一段TCP报文
- 标志位为ACK,表示“确认收到服务器端同意连接的信号”(即告诉服务器,我知道你收到我发的数据了);
- 序号为Seq=x+1,表示收到服务器端的确认号Ack,并将其值作为自己的序号值;
- 确认号为Ack=y+1,表示收到服务器端序号Seq,并将其值加1作为自己的确认号Ack的值;
- 随后客户端进入ESTABLISHED阶段。(即成功建立了连接)
关于确认号ACK和数据包的序号Seq值的变化
- ACK确认号:就是确认收到消息后 返回给 发送端的 序号(ACK = 发起方的Seq + 1) 即就是下次发送的端的seq序号。Seq数据包序号:给每个数据包一个序号,保证接受端可以按序收到数据包(首次握手的时候 Seq = 上次握手的时候的Ack值,如果没有 则可以是任意值)
- 在客户端与服务器端传输的TCP报文中,双方的确认号Ack和序号Seq的值,都是在彼此Ack和Seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性。一旦出现某一方发出的TCP报文丢失,便无法继续"握手",以此确保了"三次握手"的顺利完成。
TCP四次挥手的过程:
四次挥手是TCP连接的释放,必须是一方主动释放,另一方被动释放。挥手之前主动释放连接的客户端结束ESTABLISHED阶段,随后开始进行“四次挥手”:
第一次挥手:首先客户端想要释放连接,向服务器端发送一段TCP报文,其中
- 标记位为FIN,表示“请求释放连接“;
- 序号为Seq=U;
- 随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。
注意:这里不发送的是正常连接时传输的数据(非确认报文),而不是一切数据,所以客户端仍然能发送ACK确认报文。
第二次挥手:服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文,其中:
- 标记位为ACK,表示“接收到客户端发送的释放连接的请求”;
- 序号为Seq=V;
- 确认号为Ack=U+1,表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值;
- 随后服务器端开始准备释放服务器端到客户端方向上的连接。客户端收到从服务器端发出的TCP报文之后,确认了服务器收到了客户端发出的释放连接请求,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段前"两次挥手"既让服务器端知道了客户端想要释放连接,也让客户端知道了服务器端了解了自己想要释放连接的请求。于是,可以确认关闭客户端到服务器端方向上的连接了
第三次挥手:服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文,其中:
(第二次挥手 服务器端回复 确认收到 客户端想要释放连接的请求 返回ACK,但是 服务端还有些数据的处理,所以不能马上断开连接,所以需要第三次握手 即服务端发送 FIN 释放连接的标志位)
- 标记位为FIN,ACK,表示“已经准备好释放连接了”。注意:这里的ACK并不是确认收到服务器端报文的确认报文。
- 序号为Seq=W;
- 确认号为Ack=U+1;表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值。随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。
第四次挥手:客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务器端发送一段报文,其中:
- 标记位为ACK,表示“接收到服务器准备好释放连接的信号”。
- 序号为Seq=U+1;表示是在收到了服务器端报文的基础上,将其确认号Ack值作为本段报文序号的值。
- 确认号为Ack=W+1;表示是在收到了服务器端报文的基础上,将其序号Seq值作为本段报文确认号的值。随后客户端开始在TIME-WAIT阶段等待2MSL。服务器端收到从客户端发出的TCP报文之后结束LAST-ACK阶段,进入CLOSED阶段。由此正式确认关闭服务器端到客户端方向上的连接。客户端等待完2MSL之后,结束TIME-WAIT阶段,进入CLOSED阶段,由此完成“四次挥手”。
注意:后面的“两次挥手”既让客户端知道了服务器端准备好释放连接了,也让服务器端知道了客户端了解了自己准备好释放连接了。于是,可以确认关闭服务器端到客户端方向上的连接了,由此完成“四次挥手”。
MSL(Maximum Segment Lifetime):最长的报文段寿命
2MSL是指最长报文段寿命的2倍,也就是2个TCP报文段在网络中最长存活时间的上限,客户端在发送完最后一个ACK报文段后,会进入TIME_WAIT状态,并开始计时2MSL的时间,在这个状态下客户端会维持连接状态,并且可以应对可能出现的延迟或者重传报文段。等待2MSL的目的是确保服务器能够收到客户端的确认,并且将可能在传输过程中未及时处理的报文段消耗掉,在等待2MSL时间之后,客户端可以关闭该连接并释放相关资源。