/ TCP 连接建立 /
当我们浏览网页、发送电子邮件或者进行在线游戏时,我们常常不会想到背后复杂的网络连接过程。然而,正是这些看似不起眼的步骤,确保了我们与服务器之间的稳定通信。其中最重要的步骤之一就是 TCP 连接的建立,而其中的核心环节就是三次握手。
本文将详细探讨三次握手的原理、过程以及其重要性。我们将一步步解析为什么需要三次握手,它如何保证连接的稳定性和可靠性,以及它对于数据传输的重要作用。通过深入理解三次握手,我们将更好地理解网络通信的底层机制,并对 TCP 连接的可靠性有更清晰的认识。
1
TCP 是一种面向连接的传输层协议,它在进行数据传输之前需要先建立连接。这个连接的建立过程是通过三次握手来完成的。
我们根据这幅图详细讲解,每次连接中所发送的 TCP 报文。
在最开始,客户端和服务端都处于 CLOSED 状态。首先,服务端主动监听某个端口,处于 LISTEN 状态,即服务器必须处于启动状态。接下来,客户端准备开始访问网页,需要与服务器建立连接。第一次连接报文的格式如下:
客户端在发起连接时,会随机生成一个初始序号(client_isn),并将其放置在 TCP 首部的”序号”字段中。同时,客户端将 SYN 标志位置为 1,表示发出的报文是 SYN 报文。客户端通过发送第一个 SYN 报文给服务端,表明它希望与服务端建立连接。该报文不包含应用层数据(也就是发送的数据)。此时,客户端的状态被标记为 SYN-SENT。
当服务端收到客户端的 SYN 报文时,首先服务端会随机初始化自己的序号(server_isn),然后将该序号填入 TCP 首部的”序号”字段中。接着,服务端将”确认应答号”字段填入 client_isn + 1,并将 SYN 和 ACK 标志位都设置为 1。最后,服务端将该报文发送给客户端,该报文不包含应用层数据(此时服务器也没数据可发)。此时,服务端处于 SYN-RCVD 状态。
一旦客户端收到服务端的报文,它需要做以下优化来回应最后一个应答报文:首先,客户端将该应答报文的 TCP 首部的 ACK 标志位设置为 1;其次,客户端在”确认应答号”字段中填入 server_isn + 1 的值;最后,客户端将报文发送给服务端。此次报文可以携带客户端到服务器的数据。完成这些操作后,客户端将进入 ESTABLISHED 状态。
一旦服务器收到客户端的应答报文,它也会切换到 ESTABLISHED 状态。
从上面的过程可以发现,在进行三次握手时,第三次握手是可以携带数据的,而前两次握手则不可以。这也是面试中经常被问到的问题。一旦完成三次握手,双方都会进入 ESTABLISHED 状态,表示连接已经成功建立,此时客户端和服务端就可以开始相互发送数据了。
2
相信大家通常回答的是:“因为三次握手才能保证双方具有接收和发送的能力。”这个回答没错,但它只是表面上的原因,并没有提出主要的原因。下面我将从三个方面分析三次握手的原因,加深我们对这个问题的理解。
三次握手可以有效地避免历史重复连接的初始化(主要原因)
三次握手可以保证双方都收到了可靠的初始序列号。
三次握手可以避免资源浪费。
2.1
原因一:避免历史重复连接
简单来说,三次握手的主要原因是为了避免旧的重复连接初始化造成混乱。在复杂的网络环境中,数据包的传输并不总是按照规定时间发送到达目标主机,可能会因为网络拥堵等原因导致旧的数据包先到达目标主机。为了避免这种情况,TCP 使用三次握手的方式来建立连接。
当客户端连续发送多个 SYN 建立连接的报文时,在网络拥堵等情况下,可能会出现以下情况:
旧的 SYN 报文比最新的 SYN 报文先到达服务端。
服务端收到旧的 SYN 报文后会回复一个 SYN + ACK 报文给客户端。
客户端收到 SYN + ACK 报文后,根据自身的上下文判断这是一个历史连接(序列号过期或超时),然后发送 RST 报文给服务端,表示中止这次连接。
如果是两次握手的连接方式,就无法判断当前连接是否是历史连接。而三次握手可以在客户端准备发送第三次报文时,根据上下文判断当前连接是否是历史连接:
如果是历史连接(序列号过期或超时),则第三次握手发送的报文是 RST 报文,以中止历史连接。
如果不是历史连接,则第三次发送的报文是 ACK 报文,通信双方成功建立连接。
因此,TCP 使用三次握手的主要原因是为了防止历史连接初始化了连接。
2.2
原因二:同步双方初始序列号
TCP 协议的通信双方都必须维护一个序列号,这是确保可靠传输的关键因素。序列号在 TCP 连接中扮演了重要角色,它具有以下作用:
● 接收方可以消除重复的数据,确保数据的准确性。
● 接收方可以按照序列号的顺序接收数据包,保证数据的完整性。
● 序列号可以标识已经被对方接收的数据包,实现可靠的数据传输。
因此,在建立 TCP 连接时,客户端发送带有初始序列号的 SYN 报文,并需要服务器回复一个 ACK 报文,表示成功接收了客户端的 SYN 报文。然后,服务器发送带有初始序列号的 SYN 报文给客户端,并等待客户端的应答,这样一来一回,才能确保双方的初始序列号能够可靠地同步。
虽然四次握手也可以实现可靠地同步双方的初始序列号,但由于第二步和第三步可以合并为一步,所以最终演变成了三次握手。而两次握手只能保证一方的初始序列号被对方成功接收,无法保证双方的初始序列号都能被确认接收。因此,三次握手是为了确保 TCP 连接的稳定性和可靠性而采取的最佳选择。
2.3
原因三:避免资源浪费
如果只有”两次握手”的话,当客户端的 SYN 请求在网络中被阻塞时,客户端无法接收到服务器发送的 ACK 报文,因此会重新发送 SYN。然而,由于没有第三次握手,服务器无法确定客户端是否收到了建立连接的 ACK 确认信号。因此,服务器只能在收到每个 SYN 请求后主动建立一个连接。这将导致以下情况的发生:
资源浪费:如果客户端的 SYN 请求被阻塞,导致重复发送多个 SYN 报文,服务器在收到请求后将建立多个冗余的无效连接。这将导致服务器资源的不必要浪费。
消息滞留:由于缺乏第三次握手,服务器无法知道客户端是否正确接收到了建立连接的 ACK 确认信号。因此,如果消息在网络中出现滞留,客户端将一直重复发送 SYN 请求,导致服务器不断建立新的连接。这将增加网络拥塞和延迟,并对整个网络性能产生负面影响。
因此,为了确保网络连接的稳定性和可靠性,TCP 使用了三次握手来建立连接,以避免以上问题的发生。
/ 总结 /
TCP 连接建立是通过三次握手来完成的。在三次握手过程中,客户端首先发送一个带有 SYN 标志的报文给服务器,表示希望建立连接。服务器接收到客户端的请求后,回复一个带有 SYN 和 ACK 标志的报文给客户端,表示接受连接请求,并发送自己的初始序列号。最后,客户端再回复一个带有 ACK 标志的报文给服务器,表示连接建立成功。这样,双方就进入了 ESTABLISHED 状态,可以开始相互发送数据。
总的来说,TCP 连接建立的三次握手过程是为了确保连接的稳定性和可靠性,避免历史连接的混乱和资源浪费,同时保证双方都具备接收和发送数据的能力。
原文始发于微信公众号(灵墨AI探索室):TCP连接的关键之谜:揭秘三次握手的必要性
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/208577.html