TCP三次握手和四次挥手

一、概述

  • 传输连接就有三个阶段,即:连接建立、数据传送和连接释放。

  • 连接建立过程中要解决以下三个问题:

    要使每一方能够确知对方的存在。

    要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)。

    能够对运输实体资源(如缓存大小,连接表中的项目等)进行分配。

二、 三次握手

TCP连接建立时,通过三次握手实现

1、三次握手流程

image-20210110145115993

  • 第一次握手:A先向B发送一个同步数据包(报文)。

    在数据包的TCP首部中:标志位:同步SYN为1,表示这是一个请求建立连接的数据包;

    ​ 确认标记位ACK为0,说明该数据包的确认号无效,所以该标志位可省略;

    ​ 序号Seq=x,x为所传送数据的第一个字节的序号。

  • 第二次握手:B收到A发送的第一个数据包后,决定是否同意连接,若同意,则B发送一个数据包进行回应

    在数据包的TCP首部中:标志位:同步SYN=1;

    标志位:确认ACK=1;

    序号seq=y;表示B给A的第一个数据字节的序号

    确认号ack=x+1; 表示已经收到A发送的x个字节数据,并告诉A下次应从数据的第x+1个字节开始发送。

    只有确认位ACK为1时,确认号才有效

  • 第三次握手:A收到B的确认之后,再给A发送一个数据包。

    在数据包的TCP首部中:已经没有有效的标志位:同步SYN了(即SYN=0),表示双方已同意建立连接;

    标志位确认ACK=1,表示收到B的确认数据包;

    序号seq=x+1; 表示A给B的第一个数据字节的序号

    确认号ack=y+1,表示收到了B发送y字节数据,并告诉B下次应从数据的第y+1个字节开始发送。

2、三次握手建立TCP连接过程的各状态

image-20210110145127337

A发出请求建立连接的数据包之后进入SYN-SENT状态,表示发送了请求建立连接的同步数据包。

B收到A发出的请求建立连接的数据包之后,结束LISTEN状态,进入SYN-RCVD状态并向A发出确认数据包。

A收到确认数据包之后,结束SYN-SENT状态,进入ESTABLISHED状态,并向B发送确认数据包。

B收到A的确认数据包之后,结束SYN-RCVD状态,进入ESTABLISHED状态。

A与B都进入ESTABLISHED状态之后,开始传输数据,由此完成三次握手。

  • 测试

    SYN-SENT==》 通过访问一个不存在的地址,自己一直收不到确认连接状态,就会一直处于SYN-SENT状态

image-20210110145244470

3、为什么需要三次握手?

​ 如果是两次握手,即A发给B要建立连接,B回复确认信息。会有以下问题:(syn攻击)

1、当A给B发建立请求的数据包时,由于网络原因,B还没有收到 ==》 A以为超时了

2、A再给B发建立请求的数据包,这次很快,B收到了。并且回复确认信息。两台主机建立了连接

3、此时A发的第一个建立连接的数据包终于到了B那里,B以为是再次建立连接,于是又发送确认信息

4、A收到确认信息,一看我已经建立连接了,所以就丢掉不管。 但是B不知道,以为建立了连接,会有A的数据。但A永远也不会发送数据过来

​ 第三次握手(第三个数据包)作用在于,告诉B计算机,B第二次握手发给A的确认数据包A收到了,是有效的。避免B计算机等待造成资源浪费。随后A与B可进行下一步的通信。

4、抓包验证

网页访问 https://www.cnblogs.com/

该网站的ip地址为:

image-20210110145556544

以下为抓包结果:(可以看到经过三次握手后,建立了连接。后面就可以发送消息了)

image-20210110145605985

三、四次挥手

1、四次挥手过程

TCP连接释放,通过四次挥手实现

所谓的四次挥手即TCP连接的释放(解除)。连接的释放必须是一方主动释放,另一方被动释放。

​ 数据传输结束后,通信的双方都可主动释放连接。下为A主动释放TCP连接。

image-20210110145857199

  • 第一次挥手:首先A向B发送连接释放请求报文(数据包),并停止发送数据。

    在连接释放报文(数据包)的TCP首部中:标志位:终止FIN=1,意味着A要主动释放A—>B的TCP连接;

    ​ 序号位seq为u,u值由A指定。随后等待B的确认。

    此时A的状态变为FIN-WAIT-1。B还没有收到数据包,状态还是ESTABLISHED

  • 第二次挥手:B收到连接释放报文之后,给A发送确认报文

    此时TCP服务器进程通知高层应用进程,这样从A到B这个方向上的连接就释放了,TCP连接处于半关闭状态。

    此时A没有数据要发给B了,但是B还有数据要发送给A,A仍可以接收。

    在确认报文的TCP首部中:标志位:确认ACK=1,表示收到了A发送的数据包,同意A释放连接;‘

    序号位seq=v,v值由B指定;

    确认号ack=u+1,表示已经收到A发送的u个字节数据,并告诉A下次应从数据的第u+1个字节开始发送,下面同理;此时B还可以向A传输数据。

    B的状态变为CLOSE_WIAT。A收到确认报文后,状态变为FIN-WAIT-2

====前两次挥手 A到B这条连接就断了(B可能还要向A发送数据)=

  • 第三次挥手:B向A发送释放连接请求

在确认报文的TCP首部中:标志位:确认ACK=1,表示B已经把需要发给A的数据发完了;

标志位:终止FIN=1,意味着B要释放B—>A的TCP连接;

序号seq=w,w值由B指定;

确认号ack=u+1;此后B不再向A发送数据,但能接收数据。

B的状态变为LAST-ACK。

  • 第四次挥手:A收到B的连接释放报文段后,向B发出确认报文。

    在确认报文的TCP首部中:标志位:确认ACK=1,表示收到B的确认报文,并同意B释放连接;

    序号seq=u+1;

    确认号ack=w+1;

    A的状态变为TIME-WAIT。B收到确认报文后,状态变为CLOSED

    A在经过2msl后,状态也变为CLOSED

由此通过四次挥手释放了TCP连接。

以下为动态过程:

Peace

2、为什么是三次握手和四次挥手?

​ 三次握手中第二次握手传递了SYN=1和ACK=1。表示需要服务端B要和客户端A建立连接,并且确认收到了客户端A的连接请求。即建立连接报文和确认报文是一起传过去的。

​ 四次挥手中ACK确认报文和FIN结束报文在第二次挥手(B向A确认收到A发来的结束请求)和第三次挥手(B向A发送结束请求)中分别发送。为什么释放连接的时候需要分开传输?

  • 建立连接时,被动方服务器端结束CLOSED阶段进入“握手”阶段并不需要任何准备,可以直接返回SYN和ACK报文,开始建立连接。(此时B是没有处理任何事的)

  • 释放连接时,被动方服务器,突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接之后,才能返回FIN释放连接报文。 (此时B正在处理自己的事,所以不能立刻结束B到A的连接)

3、为什么客户端在TIME-WAIT阶段要等2MSL?

为了确定服务端是否收到了客户端发的确认信息

MSL指的是Maximum Segment Lifetime:一段TCP报文在传输过程中的最大生命周期。

2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长。

​ 当客户端发出确认信息后,并不能保证服务端已经收到了确认数据。所以客户端在发送完确认信息后,会设置一个2MSL的计时器。

  • 服务器端在1MSL内没有收到客户端发出的ACK确认报文,就会再次向客户端发出FIN报文;
  • 如果客户端在2MSL内,再次收到了来自服务器端的FIN报文,说明服务器端由于各种原因没有接收到客户端发出的ACK确认报文。客户端再次向服务器端发出ACK确认报文,计时器重置,重新开始2MSL的计时;
  • 否则客户端在2MSL内没有再次收到来自服务器端的FIN报文,说明服务器端正常接收了ACK确认报文,客户端可以进入CLOSED阶段,完成“四次挥手”。

所以,客户端要经历时长为2SML的TIME-WAIT阶段;这也是为什么客户端比服务器端晚进入CLOSED阶段的原因

4、抓包演示四次挥手

image-20210110151808521

参考链接:

https://www.cnblogs.com/GoForMyDream/p/8707813.html

https://www.cnblogs.com/AhuntSun-blog/p/12037852.html#4691774


如果本篇博客有任何错误和建议,欢迎大佬们批评指正

我是知逆,我们下期见

原文地址:https://www.cnblogs.com/mercurytan/p/14258440.html