关于三次握手详解,让你更加理解

使用TCP协议进行通信的双方主机,在进行数据传输之前,必须使用“三次报文握手”来建立TCP连接。TCP连接建立成功后才能进行数据传输,数据传输完成后必须使用“四次报文挥手”来释放TCP连接。而TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。那么为什么是三次握手,而不是两次呢?中途丢包又该怎么办?关于三次握手的十个问题你知道几个?今天就一起回顾下三次握手的原理和注意事项,下次再碰到问题轻松解决!

TCP报文段简介

在介绍三次握手和四次挥手之前,先来简单认识一下 TCP 报文段的结构

TCP报文段也分为首部和数据两部分,首部默认情况下一般是20字节长度,但在一些需求情况下,会使用“可选字段”,这时,首部长度会有所增加,但最长不超过60字节。

TCP 首部包含以下内容,请留意其中的控制位,在三次握手和四次挥手过程中会频繁出现:

1.端口号 (Source Port and Destination Port):每个 TCP 报文段都包含源端和目的端的端口号,用于寻找发送端和接收端应用进程。这两个值加上 IP 首部中的源端 IP 地址和目的端 IP 地址就可以确定一个唯一的 TCP 连接。

2.序号 (Sequence Number):这个字段的主要作用是用于将失序的数据重新排列。TCP 会隐式地对字节流中的每个字节进行编号,而 TCP 报文段的序号被设置为其数据部分的第一个字节的编号。序号是 32 bit 的无符号数,取值范围是0到 232 - 1。

3.确认序号 (Acknowledgment Number):接收方在接受到数据后,会回复确认报文,其中包含确认序号,作用就是告诉发送方自己接收到了哪些数据,下一次数据从哪里开始发,因此,确认序号应当是上次已成功收到数据字节序号加 1。只有 ACK 标志为 1 时确认序号字段才有效。

4.首部长度 (Header Length):首部中的选项部分的长度是可变的,因此首部的长度也是可变的,所以需要这个字段来明确表示首部的长度,这个字段占 4 bit,4 位的二进制数最大可以表示 15,而首部长度是以 4 个字节为一个单位的,因此首部最大长度是 15 * 4 = 60 字节。

5.保留字段 (Reserved):占 6 位,未来可能有具体用途,目前默认值为0.

6.控制位 (Control Bits):在三次握手和四次挥手中会经常看到 SYN、ACK 和 FIN 的身影,一共有 6 个标志位,它们表示的意义如下:

①URG (Urgent Bit):值为 1 时,紧急指针生效

②ACK (Acknowledgment Bit):值为 1 时,确认序号生效

③PSH (Push Bit):接收方应尽快将这个报文段交给应用层

④RST (Reset Bit):发送端遇到问题,想要重建连接

⑤SYN (Synchronize Bit):同步序号,用于发起一个连接

⑥FIN (Finish Bit):发送端要求关闭连接

5.窗口大小 (Window):TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个 16 bit 字段,单位是字节, 因而窗口大小最大为 65535 字节。

6.检验和 (Checksum):功能类似于数字签名,用于验证数据完整性,也就是确保数据未被修改。检验和覆盖了整个 TCP 报文段,包括 TCP 首部和 TCP 数据,发送端根据特定算法对整个报文段计算出一个检验和,接收端会进行计算并验证。

7.紧急指针 (Urgent Pointer):当 URG 控制位值为 1 时,此字段生效,紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。

8.选项 (Options):这一部分是可选字段,也就是非必须字段,最常见的可选字段是“最长报文大小 (MSS,Maximum Segment Size)”。

9.有效数据部分 (Data):这部分也不是必须的,比如在建立和关闭 TCP 连接的阶段,双方交换的报文段就只包含 TCP 首部。

TCP是什么

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793 定义。

TCP旨在适应支持多网络应用的分层协议层次结构。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。TCP假设它可以从较低级别的协议获得简单的,可能不可靠的数据报服务。 原则上,TCP应该能够在从硬线连接到分组交换或电路交换网络的各种通信系统之上操作。

传输控制协议(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。 

互联网络与单个网络有很大的不同,因为互联网络的不同部分可能有截然不同的拓扑结构、带宽、延迟、数据包大小和其他参数。TCP的设计目标是能够动态地适应互联网络的这些特性,而且具备面对各种故障时的健壮性。

不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

每台支持TCP的机器都有一个TCP传输实体。TCP实体可以是一个库过程、一个用户进程,或者内核的一部分。在所有这些情形下,它管理TCP流,以及与IP层之间的接口。TCP传输实体接受本地进程的用户数据流,将它们分割成不超过64KB(实际上去掉IP和TCP头,通常不超过1460数据字节)的分段,每个分段以单独的IP数据报形式发送。当包含TCP数据的数据报到达一台机器时,它们被递交给TCP传输实体,TCP传输实体重构出原始的字节流。为简化起见,我们有时候仅仅用“TCP”来代表TCP传输实体(一段软件)或者TCP协议(一组规则)。根据上下文语义你应该能很清楚地推断出其实际含义。例如,在“用户将数据交给TCP”这句话中,很显然这里指的是TCP传输实体。

IP层并不保证数据报一定被正确地递交到接收方,也不指示数据报的发送速度有多快。正是TCP负责既要足够快地发送数据报,以便使用网络容量,但又不能引起网络拥塞:而且,TCP超时后,要重传没有递交的数据报。即使被正确递交的数据报,也可能存在错序的问题,这也是TCP的责任,它必须把接收到的数据报重新装配成正确的顺序。简而言之,TCP必须提供可靠性的良好性能,这正是大多数用户所期望的而IP又没有提供的功能。


TCP的发展历程

TCP的正式定义由1981年9月的RFC793给出。随着时间的推移,已经对其做了许多改进,各种错误和不一致的地方逐渐被修复。

为了让你感受到TCP的扩展历程,现在重要的RFC有:RFC793plus澄清了说明,RFC1122修复了bug、RFC1323做了高性能扩展,RFC2018定义了选择性确认,RFC2581说明了拥塞控制、RFC2873定义了为服务质量而重用的头字段,RFC2988改进了重传计时器,RFC3168定义了显式拥塞通知。完整的协议集合很大,因而专门发布了一个针对许多RFC的指南,它就是作为另一个RFC文档公布的RFC4614。


TCP的主要功能

当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)限制。之后TCP把数据包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。

TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。

①在数据正确性与合法性上,TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和;同时可以使用md5认证对数据进行加密。

②在保证可靠性上,采用超时重传和捎带确认机制。

③在流量控制上,采用滑动窗口协议,协议中规定,对于窗口内未经确认的分组需要重传。

在拥塞控制上,采用广受好评的TCP拥塞控制算法(也称AIMD算法)。该算法主要包括四个主要部分:

(1)慢启动

每当建立一个TCP连接时或一个TCP连接发生超时重传后,该连接便进入慢启动阶段。进入慢启动后,TCP实体将拥塞窗口的大小初始化为一个报文段,即:cwnd=1。此后,每收到一个报文段的确认(ACK),cwnd值加1,即拥塞窗口按指数增加。当cwnd值超过慢启动阈值(ssthresh)或发生报文段丢失重传时,慢启动阶段结束。前者进入拥塞避免阶段,后者重新进入慢启动阶段。

(2)拥塞避免

在慢启阶段,当cwnd值超过慢启动阈值(ssthresh)后,慢启动过程结束,TCP连接进入拥塞避免阶段。在拥塞避免阶段,每一次发送的cwnd个报文段被完全确认后,才将cwnd值加1。在此阶段,cwnd值线性增加。

(3)快速重传

快速重传是对超时重传的改进。当源端收到对同一个报文的三个重复确认时,就确定一个报文段已经丢失,因此立刻重传丢失的报文段,而不必等到重传定时器(RTO)超时。以此减少不必要的等待时间。

(4)快速恢复

快速恢复是对丢失恢复机制的改进。在快速重传之后,不经过慢启动过程而直接进入拥塞避免阶段。每当快速重传后,置ssthresh=cwnd/2、cwnd=ssthresh+3。此后,每收到一个重复确认,将cwnd值加1,直至收到对丢失报文段和其后若干报文段的累积确认后,置cwnd=ssthresh,进入拥塞避免阶段。


TCP的主要特点

TCP是一种面向广域网的通信协议,目的是在跨越多个网络通信时,为两个通信端点之间提供一条具有下列特点的通信方式:    

(1)基于流的方式;
(2)面向连接;
(3)可靠通信方式;
(4)在网络状况不佳的时候尽量降低系统由于重传带来的带宽开销;
(5)通信连接维护是面向通信的两个端点的,而不考虑中间网段和节点。

为满足TCP协议的这些特点,TCP协议做了如下的规定:

①数据分片:在发送端对用户数据进行分片,在接收端进行重组,由TCP确定分片的大小并控制分片和重组;
②到达确认:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认;
③超时重发:发送方在发送分片时启动超时定时器,如果在定时器超时之后没有收到相应的确认,重发分片;
④滑动窗口:TCP连接每一方的接收缓冲空间大小都固定,接收端只允许另一端发送接收端缓冲区所能接纳的数据,TCP在滑动窗口的基础上提供流量控制,防止较快主机致使较慢主机的缓冲区溢出;
⑤失序处理:作为IP数据报来传输的TCP分片到达时可能会失序,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层;
⑥重复处理:作为IP数据报来传输的TCP分片会发生重复,TCP的接收端必须丢弃重复的数据;
⑦数据校验:TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到分片的检验和有差错,TCP将丢弃这个分片,并不确认收到此报文段导致对端超时并重发。


TCP的工作方式

一、建立连接

TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK,并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议。

TCP三次握手的过程如下:
1.客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SENT状态。
2.服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
3.客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。
三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。


二、连接终止

建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。具体过程如下图所示。


(1) 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
(2) 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。
注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。
(3) 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。
(4) 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。
既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。
注意:
(1) “通常”是指,某些情况下,步骤1的FIN随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭那一端,有可能被合并成一个分节。
(2) 在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为“半关闭”(half-close)。
(3) 当一个Unix进程无论自愿地(调用exit或从main函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何TCP连接上也发出一个FIN。
无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况是,客户执行主动关闭,但是某些协议,例如,HTTP/1.0却由服务器执行主动关闭。


三次握手常见问题

一、三次握手

三次握手是TCP协议用于建立可靠连接的过程,其步骤如下:

第一次握手(SYN):客户端向服务器发送SYN包,请求建立连接。该包中包含一个随机生成的初始序列号ISN(Initial Sequence Number)。

第二次握手(SYN+ACK):服务器收到SYN包后,向客户端发送SYN+ACK包,表示同意建立连接。该包中也包含一个随机生成的序列号ISN,同时将确认序列号ACK设置为客户端的ISN+1。

第三次握手(ACK):客户端收到服务器的SYN+ACK包后,向服务器发送ACK包,表示客户端也同意建立连接。该包的序列号设置为服务器的ISN+1,确认序列号设置为服务器的ISN+1。
在三次握手完成后,TCP连接建立成功,双方可以开始进行数据传输。这个过程可以确保连接的可靠性和完整性,防止数据包的丢失或重复传输。


二、三次握手的作用

1.建立可靠连接:三次握手可以确保客户端和服务器之间建立起可靠的连接,防止数据包的丢失或重复传输。

2.防止旧连接的混淆:由于网络延迟等原因,可能会出现旧连接的数据包在新连接中被误认为是有效数据包的情况。而三次握手过程中随机生成的ISN可以防止这种情况的发生。

3.防止恶意连接:三次握手可以防止未经授权的恶意连接,例如SYN洪泛攻击等。如果服务器收到的SYN包并没有相应的ACK包,那么服务器就不会认为这是一条有效的连接请求,从而防止恶意连接。

总之,三次握手是TCP协议用于建立可靠连接的基本过程,其作用在于确保连接的可靠性、完整性和安全性。

三、ISN是固定的吗

ISN(Initial Sequence Number)是随机生成的,通常由操作系统的伪随机数生成器生成。因此,每次建立连接时都会生成一个新的ISN。

ISN的目的是防止旧连接的混淆和防止恶意连接,因此它需要是随机的、不可预测的。

ISN的长度通常为32位(4字节),因此ISN的取值范围为0~2^32-1。在TCP连接建立的过程中,ISN会被客户端和服务器分别使用,以确保连接的可靠性和完整性。

需要注意的是,ISN是由操作系统生成的,而不是由应用程序生成的。这意味着在同一台计算机上运行的不同应用程序,它们建立的连接的ISN是不同的。

同时,在不同的计算机上生成的ISN也可能不同,这取决于操作系统实现ISN的方式。


四、什么是半链接序列

"半连接序列"是指在TCP三次握手过程中,当服务器收到客户端的SYN包后,它会发送一个SYN+ACK包作为响应,此时连接处于半开状态,即服务器已经准备好接收客户端的数据,但客户端还没有发送ACK包确认连接的建立。

在这种情况下,服务器会在等待一段时间(通常称为“半连接超时时间”),等待客户端发送ACK包,如果在规定的时间内没有收到客户端的ACK包,服务器会认为客户端没有接收到SYN+ACK包,进而关闭连接并释放资源。

这个过程被称为半连接队列(Half-open queue),其中等待ACK包的连接称为半连接(Half-open connection)。

半连接队列是用于存储等待客户端ACK的连接队列。在Linux操作系统中,可以使用netstat命令查看半连接队列的大小。

当半连接队列的大小超过一定阈值时,服务器可能会拒绝新的连接请求,以避免资源耗尽。因此,在设计应用程序时需要注意合理设置半连接队列的大小,以确保系统的稳定性和可靠性。


五、三次握手过程中是否可以携带数据

在TCP三次握手的过程中,不会携带应用层数据。三次握手的过程是在TCP协议层次进行的,而应用层的数据传输是在TCP连接建立之后进行的。

三次握手的过程中,客户端和服务器之间仅仅交换了一些控制信息,例如序列号、确认号等,用于建立可靠的连接和确认连接的建立。在第三次握手之后,双方的TCP协议都已经确认了连接的建立,可以进行数据传输。

一旦TCP连接建立完成,应用程序就可以使用该连接进行数据的传输。在传输数据时,数据会被封装在TCP的数据段中,然后通过TCP连接进行传输。

因此,在TCP连接建立完成之前,应用程序不能进行数据的传输。


六、三次握手的安全性怎么样

TCP三次握手是一种可靠的连接建立方式,也是一种安全的连接建立方式。它可以确保连接建立时,双方的TCP协议栈都已经认可了对方的身份,从而避免了连接被第三方篡改或冒充的风险。

在TCP三次握手的过程中,第三次握手中的ACK包中确认号(ACK number)是根据第二次握手中的序列号(Sequence number)加1生成的,这样可以确保双方都能够正确地识别对方的身份和数据传输的正确性。

同时,TCP还使用随机的ISN(Initial Sequence Number)来防止重放攻击,这使得攻击者很难猜测序列号,从而防止攻击者模拟另一方进行连接。

虽然三次握手是一种安全可靠的连接建立方式,但在实际应用中,仍然存在一些安全威胁。例如,攻击者可能通过伪造IP地址或端口号等方式进行欺骗或攻击。

因此,在实际应用中,还需要使用一些其他的安全机制来保护TCP连接的安全,例如TLS(Transport Layer Security)协议等。


七、三次握手最大的问题是什么

TCP三次握手的最大问题是SYN洪泛攻击(SYN flood attack)。

SYN洪泛攻击是一种常见的网络攻击,攻击者向服务器发送大量的SYN包,但并不发送ACK包来完成连接建立,从而导致服务器的半连接队列满,无法接受新的连接请求,最终导致服务不可用或崩溃。

SYN洪泛攻击利用了TCP三次握手的过程中,服务器需要为每一个收到的SYN包创建一个半连接的特点。

当攻击者发送大量的SYN包时,服务器需要为每一个SYN包都创建一个半连接,而由于攻击者不发送ACK包,这些半连接会一直保持,直到超时才会被清除,从而消耗服务器的资源,导致服务器无法正常处理新的连接请求。

为了防止SYN洪泛攻击,可以使用一些防御措施,例如在网络边界处使用防火墙、使用SYN cookie技术、调整半连接队列的大小、限制同一IP地址的连接数量等等。这些措施可以有效地缓解SYN洪泛攻击对服务器的影响。


八、三次握手还有哪些需要注意的问题

除了SYN洪泛攻击这个已经提到过的问题,TCP三次握手还有一些需要注意的问题,如下:

1.超时重传:在三次握手的过程中,如果一方没有收到对方发送的数据包,则需要重传该数据包,直到成功建立连接或达到最大重传次数。超时重传的时间应该根据实际情况进行调整,以确保在网络环境不稳定或延迟较高的情况下仍能够成功建立连接。

2.中间人攻击:TCP三次握手中的数据包可以被攻击者劫持,从而实施中间人攻击。为了防止中间人攻击,可以使用TLS协议等加密通信机制来确保通信的安全性。

3.处理半连接队列:在TCP三次握手的过程中,服务器需要维护一个半连接队列来处理未完成的连接请求。如果半连接队列满了,则无法处理新的连接请求,从而导致服务不可用。因此,在实际应用中,需要根据实际情况来调整半连接队列的大小,以避免出现此类问题。

4.不同操作系统实现的差异:不同操作系统在实现TCP协议栈时可能存在一些细微的差异,例如超时时间的设置、ISN的生成方式等。在开发应用程序时,需要考虑这些差异,以确保程序在不同操作系统上都能够正常工作。

综上所述,TCP三次握手是一种可靠的连接建立方式,但在实际应用中,还需要注意一些细节问题,以确保连接的安全和稳定。

九、TCP建立连接为什么要三次握手而不是两次?

网上大多数资料对这个问题的回答只有简单的一句:防止已过期的连接请求报文突然又传送到服务器,因而产生错误,这既不够全面也不够具体。下面给出比较详细而全面的回答:

1.防止已过期的连接请求报文突然又传送到服务器,因而产生错误 在双方两次握手即可建立连接的情况下,假设客户端发送 A 报文段请求建立连接,由于网络原因造成 A 暂时无法到达服务器,服务器接收不到请求报文段就不会返回确认报文段。

客户端在长时间得不到应答的情况下重新发送请求报文段 B,这次 B 顺利到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,客户端在收到 确认报文后也进入 ESTABLISHED 状态,双方建立连接并传输数据,之后正常断开连接。

此时姗姗来迟的 A 报文段才到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,但是已经进入 CLOSED 状态的客户端无法再接受确认报文段,更无法进入 ESTABLISHED 状态,这将导致服务器长时间单方面等待,造成资源浪费。

2.三次握手才能让双方均确认自己和对方的发送和接收能力都正常

第一次握手:客户端只是发送处请求报文段,什么都无法确认,而服务器可以确认自己的接收能力和对方的发送能力正常;
第二次握手:客户端可以确认自己发送能力和接收能力正常,对方发送能力和接收能力正常
第三次握手:服务器可以确认自己发送能力和接收能力正常,对方发送能力和接收能力正常;
可见三次握手才能让双方都确认自己和对方的发送和接收能力全部正常,这样就可以愉快地进行通信了。

3.告知对方自己的初始序号值,并确认收到对方的初始序号值

TCP 实现了可靠的数据传输,原因之一就是 TCP 报文段中维护了序号字段和确认序号字段,也就是图中的 seq 和 ack,通过这两个字段双方都可以知道在自己发出的数据中,哪些是已经被对方确认接收的。

这两个字段的值会在初始序号值得基础递增,如果是两次握手,只有发起方的初始序号可以得到确认,而另一方的初始序号则得不到确认。

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值