目录
[如何唯一确定一个 TCP 连接](#如何唯一确定一个 TCP 连接)
[为什么客户端和服务端的初始序列号 ISN 不同](#为什么客户端和服务端的初始序列号 ISN 不同)
[既然 IP 层会分片,为什么 TCP 层还需要 MSS](#既然 IP 层会分片,为什么 TCP 层还需要 MSS)
[为什么TCP挥手需要有TIME WAIT状态](#为什么TCP挥手需要有TIME WAIT状态)
[快速重传(Fast Retransmit)](#快速重传(Fast Retransmit))
写在前面
本系列文章:
TCP基本概念
为什么需要TCP
IP层本身不具备可靠性特性,它不确保数据包的送达、顺序或完整性。为了实现网络数据包的可靠传输,必须依赖传输层的TCP协议。TCP提供了一种可靠的传输服务,确保数据包在接收端无损、连续、无重复且按正确顺序到达。
什么是TCP
TCP是一种面向连接、可靠且基于字节流的传输层通信协议。其特点包括:
- **面向连接:**TCP建立的连接是点对点的,不支持一对多的广播式通信,这与UDP的多播能力形成对比。
- **可靠性:**TCP能够在各种网络条件下确保数据包的送达,即使在网络链路变化的情况下也能保证数据的完整传输。
- **字节流:**TCP传输的数据是连续的字节流,没有明确的边界,因此可以传输任意大小的消息。此外,TCP保证数据的顺序性,只有当所有前序数据都到达后,才会将数据传递给应用层,并能自动丢弃重复的数据包。
什么是TCP链接
RFC 793定义了「连接」的概念:
它涉及一系列状态信息,这些信息共同确保了通信的可靠性和流量控制。这些状态信息包括套接字(Socket)、序列号和窗口大小。因此,建立一个TCP连接需要客户端和服务器就这些关键信息达成一致。
- **套接字(Socket):**由IP地址和端口号组成,用于标识通信的两端。
- **序列号:**用于解决数据包乱序问题,确保数据的正确排序。
- **窗口大小:**用于流量控制,调节数据传输速率以避免接收方过载。
如何唯一确定一个 TCP 连接
TCP连接可以通过一个四元组唯一标识,该四元组包含以下元素:
- **源地址:**标识发送方的IP地址。
- **源端口:**指定发送方的应用程序端口。
- **目的地址:**标识接收方的IP地址。
- **目的端口:**指定接收方的应用程序端口。
源地址和目的地址(各32位)位于IP头部,负责通过IP协议将数据包发送到目标主机。源端口和目的端口(各16位)位于TCP头部,用于指示TCP协议将数据包转发给正确的进程。
TCP三次握手
握手流程
**TCP三次握手(Three-Way Handshake)**是建立一个可靠的、面向连接的通信会话的过程。它确保了两端的发送和接收能力都是就绪的,从而可以开始数据传输。以下是TCP三次握手的详细步骤:
-
SYN:初始的同步步骤。客户端发送一个带有SYN(同步序列编号)标志的TCP段到服务器,以初始化一个连接。这个SYN段包含客户端的初始序列号(ISN),用于确保数据传输的可靠性。
-
SYN-ACK:同步和确认步骤。服务器收到客户端的SYN段后,如果同意建立连接,会回复一个带有SYN和ACK(确认应答)标志的TCP段。这个SYN-ACK段包含了服务器的初始序列号,同时也确认了客户端的SYN段。
-
ACK:最终的确认步骤。客户端收到服务器的SYN-ACK段后,会发送一个带有ACK标志的TCP段作为响应。这个ACK段确认了服务器的SYN段,完成三次握手过程。
三次握手完成后,客户端和服务器都确认了对方的发送和接收能力,一个稳定的TCP连接就建立了。这个过程不仅确保了连接的可靠性,还防止了过时的连接请求突然传送到服务器,从而避免了潜在的错误。
为什么是三次握手,而不是两次、四次
TCP三次握手的原因可以从以下三个方面进行分析:
-
防止历史连接的重复初始化:这是三次握手的主要原因。RFC 793指出,三次握手的核心目的是防止旧的重复连接请求导致混乱。在网络环境中,数据包可能会因网络拥堵等原因延迟到达,甚至比新的数据包先到达目标主机。三次握手通过序列号和上下文信息,使客户端能够识别并终止历史连接,避免因旧的连接请求而建立不必要的连接。
-
同步双方的初始序列号:TCP通信双方必须维护一个序列号,这是可靠传输的关键。序列号的作用包括:去除重复数据、按序接收数据包、标识已接收的数据包。因此,当客户端发送带有初始序列号的SYN报文时,需要服务器的ACK响应来确认接收;同样,服务器发送初始序列号时也需要客户端的确认。三次握手确保了双方的初始序列号被可靠同步。
-
避免资源浪费:三次握手减少了不必要的资源开销。如果使用两次握手,将无法防止历史连接的建立,可能导致资源浪费,并且无法可靠同步双方的序列号。而四次握手虽然也能同步序列号,但三次握手已经是最少的可靠连接建立步骤,因此没有必要增加通信次数。
**总结:**TCP通过三次握手防止历史连接的建立,减少双方不必要的资源开销,并帮助双方同步初始序列号。序列号确保数据包不重复、不丢失且按序传输。不使用两次握手和四次握手的原因在于:两次握手无法防止历史连接的建立和资源浪费,也无法可靠同步序列号;而三次握手已经是最少的可靠连接建立步骤,无需更多的通信次数。
为什么客户端和服务端的初始序列号 ISN 不同
为了避免旧连接的残留报文干扰新连接,每次建立TCP连接时都会重新初始化一个新的序列号。这样做的主要目的是:
-
区分报文:通过为每个新连接分配一个独特的序列号,通信双方可以准确识别并丢弃不属于当前连接的报文段,从而避免数据错乱。
-
增强安全性:防止恶意用户伪造具有相同序列号的TCP报文,并使其被对方接收。独特的序列号使得攻击者难以预测有效的序列号,从而提高了连接的安全性。
既然 IP 层会分片,为什么 TCP 层还需要 MSS
首先先解释两个概念:
-
MTU(Maximum Transmission Unit):指一个网络包的最大长度,以太网中通常为1500字节。
-
MSS(Maximum Segment Size):指除去IP和TCP头部后,一个网络包所能容纳的TCP数据的最大长度。
如果TCP报文(头部+数据)交给IP层进行分片,可能会导致以下问题:
-
IP层分片的隐患:当IP层需要发送的数据超过MTU时,它会将数据分片成多个小于MTU的片段。目标主机的IP层负责重组这些片段后再交给TCP层。然而,如果其中一个IP分片丢失,整个IP报文的所有分片都需要重传,因为IP层本身没有超时重传机制,这由TCP层负责。
-
TCP层的重传效率:当接收方发现TCP报文(头部+数据)的某一分片丢失时,不会发送ACK给发送方。发送方的TCP层在超时后会重传整个TCP报文(头部+数据),这导致IP层分片传输效率低下。
因此,为了提高传输效率,TCP协议在建立连接时通常会协商双方的MSS值。当TCP层发现数据超过MSS时,它会先进行分片,确保形成的IP包长度不会超过MTU,从而避免IP层分片。通过TCP层分片,如果一个TCP分片丢失,重发时以MSS为单位进行,而不需要重传所有分片,显著提高了重传效率。
TCP四次挥手
挥手流程
**TCP四次挥手(Four-Way Handshake)**是终止一个TCP连接的过程。它确保了数据的完整性,并允许双方有序地关闭连接。以下是TCP四次挥手的详细步骤:
-
**FIN:**当一方(通常是客户端)完成数据发送并希望关闭连接时,它会发送一个带有FIN(结束)标志的TCP段。这个FIN段表示发送方已经没有更多数据要发送了,但它仍然可以接收数据。
-
**ACK:**接收方(通常是服务器)收到FIN段后,会发送一个带有ACK(确认)标志的TCP段作为响应。这个ACK段确认了FIN段的接收,但此时连接尚未完全关闭,因为接收方可能还有数据要发送。
-
**FIN:**当接收方也完成数据发送并准备好关闭连接时,它会发送一个带有FIN标志的TCP段。这表示接收方也没有更多数据要发送了。
-
**ACK:**最后,发送方收到第二个FIN段后,会发送一个带有ACK标志的TCP段作为响应,确认FIN段的接收。此时,连接正式关闭。
四次挥手确保了双方都有机会发送完所有数据,并确认对方已经接收完所有数据。这个过程允许TCP连接优雅地关闭,避免了数据丢失或不完整的情况。四次挥手的目的是:
-
确保双方都明确知道对方已经没有数据要发送。
-
避免连接突然中断导致的数据丢失。
-
允许双方在关闭连接前完成所有必要的数据传输和确认。
为什么挥手需要四次
从挥手过程可以看出,服务器通常需要时间来完成数据的发送和处理,因此服务器的ACK和FIN包通常分开发送。这导致了四次挥手比三次握手多了一次交互。这种设计确保了双方都有机会完成数据传输,并确认对方已经接收完所有数据,从而优雅地关闭TCP连接。
为什么TCP挥手需要有TIME WAIT状态
-
**确保最终的ACK被成功接收:**在TCP四次挥手过程中,主动关闭连接的一方在发送最后一个ACK确认包后,会进入TIME_WAIT状态。如果这个ACK丢失,被动关闭连接的一方未收到确认,会重发FIN报文。主动关闭的一方在TIME_WAIT状态下保持一段时间,以便能够重发ACK,确保连接正确关闭。
-
**防止旧的重复分段干扰新连接:**TCP连接关闭后,可能会有延迟或失效的报文仍在网络中传输。如果立即使用相同的IP地址和端口建立新连接,可能会受到这些旧报文的干扰。TIME_WAIT状态确保旧连接的所有报文都超时失效后,才允许新连接使用相同的IP地址和端口,避免数据混乱。
除了四次挥手还有什么方法能断开连接
-
RST(Reset):TCP RST标志用于立即强制终止连接。发送方通过发送带有RST标志的TCP报文,指示接收方立即断开连接。
-
超时(Timeout):如果连接在设定的超时时间内未传输任何数据包,连接双方可以自动断开连接。
TCP重传机制
TCP实现可靠传输的关键机制之一是序列号和确认应答。当数据到达接收端时,接收端会返回确认应答消息。然而,网络环境复杂,数据传输可能遇到问题,如数据包丢失。为此,TCP采用了多种重传机制来应对数据丢失。
超时重传
发送数据时,TCP设置一个定时器。如果在指定时间内未收到对方的ACK确认应答,将重发数据。超时重传适用于数据包丢失或确认应答丢失的情况。
-
超时时间(RTO):RTO(Retransmission Timeout)是超时重传时间的指标。RTO的设置应略大于报文往返时间(RTT),以确保重传机制的效率。
-
RTO设置的影响:如果RTO过长,重传会延迟,影响性能;如果RTO过短,可能导致不必要的重传,增加网络拥塞。
快速重传(Fast Retransmit)
快速重传机制不依赖时间,而是基于数据驱动的重传。
-
当发送端收到三个相同的ACK报文时,会在定时器过期前重传丢失的报文段。
-
快速重传解决了超时时间的问题,但面临另一个问题:重传时应选择重传丢失的单个报文段还是所有报文段。
此外,TCP还使用了其他机制如选择性确认(SACK)和重复选择性确认(D-SACK)来提高重传的效率和准确性。这些机制共同确保TCP能够在各种网络条件下实现可靠的传输。
TCP滑动窗口
在网络环境中,数据传输速率需要灵活调整以适应网络条件。发送方需要掌握接收方的处理能力,以避免过量发送数据导致接收方无法及时处理。
TCP的滑动窗口机制正是为了解决这一问题,它实现了流量控制。通过这一机制,接收方可以通知发送方其缓冲区的可用空间,发送方则根据这些信息调整数据的发送速率。滑动窗口的核心功能是平衡发送方和接收方的数据传输速率,防止发送方发送的数据超出接收方的处理能力,从而避免接收方缓冲区溢出。
此外,滑动窗口机制允许发送方在未收到上一个数据包的确认(ACK)的情况下,继续发送多个数据包。这种做法提高了网络的吞吐量,减少了因等待确认而产生的延迟,从而实现了更高效的数据传输。
TCP拥塞控制
TCP拥塞控制是一组机制,旨在防止网络过载,同时最大化网络资源的利用效率。它通过动态调整数据传输速率来适应网络条件,确保网络不会因过多的未确认数据而发生拥塞。拥塞控制的核心在于拥塞窗口(Congestion Window, cwnd),它限制了未被确认的报文段的数量。
-
慢启动(Slow Start):在连接建立初期,发送方以较慢的速度增加数据发送速率。拥塞窗口(cwnd)从一个最大报文段大小(MSS)开始,每次收到ACK后成倍增加,直到达到预设的慢启动阈值(ssthresh)或检测到网络拥塞迹象。
-
拥塞避免(Congestion Avoidance):一旦cwnd达到ssthresh,TCP进入拥塞避免阶段,cwnd的增长模式从指数增长变为每个往返时间(RTT)增加一个MSS的线性增长。这一阶段的目的是温和地探测网络容量,以维持网络的稳定性。
-
快速重传(Fast Retransmit):当发送方收到三个或更多重复的ACK时,它会立即重传疑似丢失的报文段,而不必等待超时。这一机制减少了重传延迟,加快了对数据丢失的响应。
-
快速恢复(Fast Recovery):在执行快速重传后,TCP不会回到慢启动状态,而是将cwnd减半至ssthresh,并开始线性增长cwnd,以迅速恢复到丢包前的传输速率。这种方法允许TCP更快地从丢包事件中恢复,同时避免了不必要的性能下降。
TCP与UDP
TCP和UDP区别
-
**连接性:**TCP是面向连接的协议,数据传输前必须建立连接;UDP无需建立连接,可立即传输数据。
-
**服务模式:**TCP提供一对一服务,每条连接仅连接两个端点;UDP支持一对一、一对多、多对多的通信模式。
-
**可靠性:**TCP提供可靠的数据传输,确保数据无误差、不丢失、不重复且按序到达;UDP尽力而为的传输,不保证数据的可靠交付。
-
**拥塞控制与流量控制:**TCP具备拥塞控制和流量控制机制,以确保数据传输的稳定性;UDP缺乏这些机制,即使网络拥堵,也不会影响UDP的发送速率。
-
**头部开销:**TCP头部长度较长,通常为20字节,若使用选项字段则更长;UDP头部固定为8字节,开销较小。
-
**传输方式:**TCP流式传输,无边界,但保证数据顺序和可靠性;UDP分包传输,有边界,但可能导致数据包丢失和乱序。
-
**分片处理:**TCP数据大于最大段大小(MSS)时,在传输层分片,接收端在传输层重组。若分片丢失,仅需重传丢失的分片;UDP数据大于最大传输单元(MTU)时,在IP层分片,接收端在IP层重组。若分片丢失,实现可靠传输的UDP需重传所有数据包,效率较低。因此,UDP报文通常应小于MTU。
TCP和UDP的应用场景
**TCP:**由于其面向连接的特性以及对数据可靠交付的保证,TCP常用于需要高可靠性的应用,如:
-
**FTP:**文件传输协议,需要确保文件数据的完整性和顺序。
-
**HTTP/HTTPS:**超文本传输协议及其安全版本,用于网页浏览,要求数据的准确传输。
**UDP:**由于其无连接的特性,能够即时发送数据,且处理简单高效,UDP常用于以下场景:
- 数据包总量较少的通信: 如DNS (域名系统)和SNMP(简单网络管理协议),这些应用对实时性要求高,而对数据丢失的容忍度也较高。
- **多媒体通信:**如视频和音频流,这些应用需要快速传输,即使偶尔丢包也不会显著影响用户体验。
- **广播通信:**UDP支持一对多的广播通信,适用于需要向多个接收者发送相同数据的场景。