目录
什么是TCP
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它负责在网络中的两个应用程序之间提供可靠的数据传输,确保数据按顺序、无差错、不丢失地传输。
TCP的特点
面向连接:通信双方在数据交换之前需要先建立连接,连接建立后才能进行数据传输,传输结束后再释放连接。
可靠性:TCP使用确认、重传、超时和流量控制等机制来保证数据的可靠传输。确认机制确保接收方可以确认已成功接收的数据,重传机制在数据丢失时重新发送,超时机制用于处理长时间没有收到确认的情况,流量控制则用于避免发送方发送过多数据导致接收方缓冲区溢出。
字节流传输:TCP将应用程序交给它的数据视为一连串的字节流,而不是分割成独立的消息。TCP负责将这些数据分割成合适的数据包并交给IP层进行传输。
拥塞控制:TCP通过拥塞窗口控制机制来避免网络拥塞,并通过动态调整发送速率来适应网络状况,以保证网络吞吐量的最优化。
全双工通信:TCP连接支持全双工通信,即双方可以同时进行数据发送和接收。
流量控制:TCP使用滑动窗口协议来进行流量控制,确保发送方和接收方之间的数据传输速率合理,不至于造成数据丢失或拥塞。
TCP通信步骤
三次握手(建立连接)
- 客户端向服务器发送一个连接请求报文段(SYN),并指明初始化序列号。
- 服务器收到请求后,如果同意连接,则发送一个确认报文段(ACK),同时也指明自己的初始化序列号。
- 客户端收到确认后,再向服务器发送确认报文段(ACK),此时连接建立成功,可以开始传输数据。
第一次握手(SYN):
- 客户端发送一个特定的TCP报文段,其中包含一个SYN(同步)标志位设置为1,同时选择一个初始序列号(ISN)。
- 这个报文段告诉服务器,客户端想要建立连接,并且客户端的初始序列号是多少。
第二次握手(SYN + ACK):
- 服务器收到客户端的SYN报文段后,如果同意建立连接,会发送一个响应。这个响应的TCP报文段中,SYN标志位设置为1(表示同步),ACK标志位也设置为1(表示确认)。同时,服务器也选择一个自己的初始序列号(ISN)。
第三次握手(ACK):
- 客户端收到服务器的响应后,会发送最后一个确认报文段。这个报文段的ACK标志位设置为1,确认服务器的初始序列号,并且可以携带数据。
- 这个报文段告诉服务器,客户端已经收到了服务器的确认,连接建立成功。可以开始发送数据了。
数据传输
连接建立后,双方可以开始通过TCP连接传输数据。数据被分割成TCP数据段,每个数据段包含一个序列号,用于在接收端重新组装数据,序列号保证数据的顺序传输,并使用确认(ACK)来保证数据的可靠性,ACK会告诉发送端已经接收到了哪些数据。
四次挥手(连接释放)
客户端或服务器任何一方都可以发起连接的释放,释放过程分为四个步骤:
- 第一步:某一方发送一个连接释放报文段(FIN)。
- 第二步:另一方收到后发送确认报文段(ACK)作为确认。
- 第三步:当另一方也准备好释放连接时,发送一个连接释放报文段(FIN)。
- 第四步:对方收到后发送确认报文段(ACK),连接关闭。
第一次挥手(FIN):
- 客户端:当客户端的应用程序决定关闭连接时,会发送一个带有FIN(Finish,结束)标志位设置为1的TCP报文段给服务器,表示客户端不再发送数据。
- 客户端进入FIN-WAIT-1状态,等待服务器的确认或拒绝。
第二次挥手(ACK):
- 服务器:服务器收到客户端的FIN报文段后,会发送一个ACK(Acknowledgement,确认)报文段给客户端,表示已经收到了客户端的关闭请求。
- 服务器进入CLOSE-WAIT状态,此时服务器可以继续发送数据给客户端。
第三次挥手(FIN):
- 服务器:当服务器的应用程序决定关闭连接时,会发送一个带有FIN标志位设置为1的TCP报文段给客户端,表示服务器也准备好关闭连接。
- 服务器进入LAST-ACK状态,等待客户端的最后确认。
第四次挥手(ACK):
- 客户端:客户端收到服务器的FIN报文段后,会发送一个ACK报文段给服务器作为确认。这个ACK报文段表示客户端确认了服务器的关闭请求。
- 客户端进入TIME-WAIT状态,等待可能出现的延迟报文段,确保对最后一个ACK的确认。
在客户端发送最后一个ACK之后,连接进入完全关闭状态。服务器在接收到这个确认后也会关闭连接。TIME-WAIT状态的持续时间通常是两个最大段生存期(Maximum Segment Lifetime,MSL),这个时间段过后,客户端可以关闭连接并释放资源。
四次挥手确保了双方的数据都能完整地传输和接收,同时避免了连接中可能出现的延迟数据影响后续连接的正常建立。
为什么要进行三次握手?两次握手行不行?一次握手行不行?
TCP采用三次握手的设计是为了确保双方都能正确同步序列号(Sequence Number),以及确认彼此已经准备好发送和接收数据。两次握手不足以满足TCP连接建立的安全性和可靠性要求,主要原因如下:
序列号同步:在TCP的通信过程中,每个数据包都包含一个序列号,用于标识数据包在传输过程中的顺序。通过三次握手,客户端和服务器能够确保彼此已经同步了初始的序列号,从而可以正常地进行数据传输。如果只有两次握手,可能无法准确确认双方的序列号是否同步,容易导致混乱或错误的数据传输。
防止旧连接的影响:三次握手可以有效地防止旧连接请求对网络造成不必要的负担。第三次握手中,服务器对客户端的确认可以避免在网络中出现旧的连接请求被错误接收的情况,确保连接的唯一性和正确性。
安全性:三次握手提供了一种简单而有效的机制,可以防止恶意的连接请求攻击(如SYN洪泛攻击)。通过客户端和服务器交换多次握手的信息,网络可以更可靠地识别和验证连接请求的合法性。
因此,尽管两次握手理论上可以建立起连接,但为了确保可靠性、安全性,TCP设计采用了三次握手的方式,这已经被广泛认可并且被实践证明是有效的连接建立方式。
两次握手在某些特定的情况下工作,但是它没有三次握手有的可靠性和安全性:
序列号同步问题:两次握手只有客户端发起连接请求并且服务器确认后建立连接。在这种情况下,客户端发送的序列号是固定的,而服务器的序列号还未被确认。这可能导致不同步的序列号,从而引发数据传输问题或安全性问题。
连接确认的不完全性:两次握手无法完全确认服务器是否真的愿意接受连接。如果客户端发送了连接请求,但是服务器没有及时响应或者响应丢失,客户端无法确认服务器是否真的愿意建立连接。
一次握手在TCP中是不可能的,因为建立连接需要双方进行通信,至少需要一个往返的传输来确认连接的建立。一次握手无法实现双方的确认和同步,也无法满足TCP连接建立的基本要求。
为什么是四次挥手?三次、两次挥手行不行?
TCP采用四次挥手的设计是为了确保在关闭连接时能够达到以下几个关键的目标和需求:
完整的数据传输:在关闭连接前,双方可能还有未传输完成的数据。四次挥手允许双方在最后关闭之前完成数据的传输和确认,确保数据不丢失和传输完整性。
双向连接的确认:TCP是全双工通信,因此在关闭连接时需要双方都能发送和接收数据。四次挥手允许客户端和服务器分别关闭它们的连接,避免了未完成的数据传输造成的不确定性。
释放网络资源:四次挥手允许双方在关闭连接后释放已分配的网络资源,如缓冲区和连接状态信息,避免资源的浪费和长时间的占用。
三次挥手的实现在理论上也是可能的,但可能会遇到以下问题:
数据传输的完整性问题:如果仅采用三次挥手,可能导致最后一些数据段在传输过程中丢失,因为接收方在发送最后的确认之前可能已经关闭了它的连接。
确认的不完整性:三次挥手可能无法完全确认双方都已经关闭了它们的连接。接收方可能会误解连接关闭的时机,导致连接状态不一致或资源未及时释放。
两次挥手是不可能的,因为TCP是全双工通信,必须在双方都确认关闭连接之前进行数据传输的完整性和正确性。一次挥手更是不可能的,因为无法在双方之间建立和确认连接关闭的过程。