类别:计算机网络 / 日期:2023-02-05 / 浏览:340 / 评论:0

(1)三次握手

image.png

三次握手(Three-way Handshake)其实就是指建立一个 TCP 连接时, 需要客户端和服务器总共发送 3 个包。进行三次握手的主要作用就是 为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序 列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端 口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗 口大小信息。-三次握手

刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态。

第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初 始化序列号 ISN,此时客户端处于 SYN_SEND 状态。

首部的同步位 SYN=1,初始序号 seq=x,SYN=1 的报文段不能携带数 据,但要消耗掉一个序号。

第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN。同时会把 客户端的 ISN + 1 作为ACK 的值,表示自己已经收到了客户端的 SYN, 此时服务器处于 SYN_REVD 的状态。-TCP

在确认报文段中 SYN=1,ACK=1,确认号 ack=x+1,初始序号 seq=y 第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当 然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了 服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收 到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起 了连接。-三次握手

确认报文段 ACK=1,确认号 ack=y+1,序号 seq=x+1(初始为 seq=x, 第二个报文段所以要+1),ACK 报文段可以携带数据,不携带数据则 不消耗序号。

那为什么要三次握手呢?两次不行吗?

为了确认双方的接收能力和发送能力都正常

如果是用两次握手,则会出现下面这种情况:

如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是 客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传 输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是 在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到 达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是 就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要 服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的 确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。 简单来说就是以下三步:-TCP

第一次握手:客户端向服务端发送连接请求报文段。该报文段中包含 自身的数据通讯初始序号。请求发送后,客户端便进入 SYN-SENT 状 态。

第二次握手:服务端收到连接请求报文段后,如果同意连接,则会发 送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成 后便进入 SYN-RECEIVED 状态。

第三次握手:当客户端收到连接同意的应答后,还要向服务端发送一 个确认报文。客户端发完这个报文段后便进入 ESTABLISHED 状态, 服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成 功。-三次握手

TCP 三次握手的建立连接的过程就是相互确认初始序号的过程,告诉 对方,什么样序号的报文段能够被正确接收。 第三次握手的作用是 客户端对服务器端的初始序号的确认。如果只使用两次握手,那么服 务器就没有办法知道自己的序号是否 已被确认。同时这样也是为了 防止失效的请求报文段被服务器接收,而出现错误的情况。-TCP

(2)四次挥手

image.png

刚开始双方都处于 ESTABLISHED 状态,假如是客户端先发起关闭请 求。四次挥手的过程如下:

第一次挥手: 客户端会发送一个 FIN 报文,报文中会指定一个序列 号。此时客户端处于 FIN_WAIT1 状态。

即发出连接释放报文段(FIN=1,序号 seq=u),并停止再发送数据, 主动关闭 TCP 连接,进入 FIN_WAIT1(终止等待 1)状态,等待服务 端的确认。

第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端 的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的 报文了,此时服务端处于 CLOSE_WAIT 状态。

即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号 ack=u+1,序号 seq=v),服务端进入 CLOSE_WAIT(关闭等待)状态, 此时的 TCP 处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入 FIN_WAIT2(终止等待 2)状态,等待服务 端发出的连接释放报文段。-三次握手

第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一 样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。

即服务端没有要向客户端发出的数据,服务端发出连接释放报文段 (FIN=1,ACK=1,序号 seq=w,确认号 ack=u+1),服务端进入 LAST_ACK (最后确认)状态,等待客户端的确认。

第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应 答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此 时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自 己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之 后,就处于关闭连接了,处于 CLOSED 状态。-TCP

即客户端收到服务端的连接释放报文段后,对此发出确认报文段 (ACK=1,seq=u+1,ack=w+1),客户端进入 TIME_WAIT(时间等待) 状态。此时 TCP 未释放掉,需要经过时间等待计时器设置的时间 2MSL 后,客户端才进入 CLOSED 状态。 -三次握手

那为什么需要四次挥手呢?

因为当服务端收到客户端的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。其中 ACK 报文是用来应答的,SYN 报文是用来同步的。 但是关闭连接时,当服务端收到 FIN 报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个 ACK 报文,告诉客户端,“你发的 FIN 报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能 发送 FIN 报文,因此不能一起发送,故需要四次挥手。-TCP

简单来说就是以下四步:

第一次挥手:若客户端认为数据发送完成,则它需要向服务端发送连 接释放请求。

第二次挥手:服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客 户端到服务端的连接已经释放,不再接收客户端发的数据了。但是因 为 TCP 连接是双向的,所以服务端仍旧可以发送数据给客户端。-三次握手

第三次挥手:服务端如果此时还有没发完的数据会继续发送,完毕后 会向客户端发送连接释放请求,然后服务端便进入 LAST-ACK 状态。

第四次挥手:客户端收到释放请求后,向服务端发送确认应答,此时 客户端进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期, 指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段 内没有服务端的重发请求的话,就进入 CLOSED 状态。当服务端收到 确认应答后,也便进入 CLOSED 状态。-TCP

TCP 使用四次挥手的原因是因为 TCP 的连接是全双工的,所以需要 双方分别释放到对方的连接,单独一方的连接释放,只代 表不能再 向对方发送数据,连接处于的是半释放的状态。

最后一次挥手中,客户端会等待一段时间再关闭的原因,是为了防止 发送给服务器的确认报文段丢失或者出错,从而导致服务器 端不能 正常关闭

版权声明 : 本文未使用任何知识共享协议授权,您可以任何形式自由转载或使用。

 可能感兴趣的文章

评论区

发表评论 / 取消回复

必填

选填

选填

◎欢迎讨论,请在这里发表您的看法及观点。

«    2023年11月    »
12345
6789101112
13141516171819
20212223242526
27282930

最新留言