三次握手四次挥手总结

Posted Jqivin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三次握手四次挥手总结相关的知识,希望对你有一定的参考价值。


三次握手

1.三次握手的过程

(1)概述:是在底层自动实现的,用户并不会参与,对用户是透明的,但是我们可以通过tcpdump抓包观察这个过程。客户端执行connect(),三次握手开始,connect返回成功,三次握手完成,客户端与服务器端建立连接。connect执行失败,三次握手建立失败。

(2)具体过程
在这里插入图片描述
在这里插入图片描述
第一次握手

  • 客户端发送SYN报文(TCP协议规定SYN=1的报文称为SYN报文,不能携带数据),选择一个初始的序列号为x,这时候client进入SYN_SENT状态。

第二次握手

  • server端接收到client发送的SYN报文,如果同意建立连接,回复一个报文(ACK=1,SYN=1 seq=y,ack=x+1),这个报文也不能携带数据. 这时候,服务端从LISTEN状态转变成了SYN_RECV状态。

第三次握手

  • TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。

三次握手若果完成,客户端的connect成功返回,服务端把连接从未连接状态队列中放到listen的已完成队列中,accept函数从已完成队列中取出已完成的连接,返回描述符。
listen方法用来创建监听队列,监听队列有两种,一种是存放未完成三次握手的连接,一种是存放已经完成三次握手的连接。listen的第二个参数就是指定已完成三次握手的队列的长度(在linux系统上,在unix系统上可能是两个队列的长度之和)。
在这里插入图片描述

accept() 处理存放在listen创建的监听队列中已完成三次握手的连接,每次处理一个连接,accept返回该连接对应的套接字的描述符。如果该队列为空,则accept阻塞。accept是否阻塞取决于监听队列(已完成三次握手的队列)是否为空。也就是说,三次握手完成了,才能执行accept();

2.TCP连接三次握手可以是两次吗?

  不可以,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
  如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

三次握手可以想象两个人在打电话

  • A:喂,能听到吗?
  • B:听得到,你能听到吗?
  • A : 能听到

3.三次握手的抓包

在这里插入图片描述

发送数据的抓包

我们只能看到TCP一般的操作,应答回复是底层自动实现的,我们看不到,所以相对于UDP来说,TCP性能下降了,但是可靠性很高。
在这里插入图片描述

四次挥手

1.四次挥手的过程

(1)图示:
在这里插入图片描述
(2)一般情况下服务器端不主动关闭,当客户端执行close(),此时,客户端发送FIN报文给服务器(序列号为u),服务器接收到此报文之后给客户端进行回应(ack=u+1),然后服务端执行close©,向客户端发送FIN报文(seq=w),客户端收到报文后,回复给服务器ACK报文(ack=w+1).

(3)具体过程

  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN_WAIT_1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号

  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE_WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE_WAIT状态持续的时间。

客户端收到服务器的确认请求后,此时,客户端就进入FIN_WAIT_2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

  1. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST_ACK(最后确认)状态,等待客户端的确认。
  2. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME_WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。

2. 为什么客户端最后还要等待2MSL?

第一,可靠的终止TCP连接。保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二保证迟来的报文有足够的时间识别并丢弃。防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。通俗来说就是,因为服务器在发送FIN报文之前还有可能有数据的传送,但是这个报文由于网络原因还没有到达,如果没有TIME_WAIT状态的话,可能客户端(相同的IP和端口)被立即重新启动,当报文到达的时候又会被接收,但是这个报文并不是应该这个客户端接受,应该是上次被关闭的客户端接受。

MSL:是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为tcp报文(segment)是ip数据报(datagram)的数据部分,具体称谓请参见《数据在网络各层中的称呼》一文,而ip头中有一个TTL域,TTL是time to live的缩写,中文可以译为“生存时间”,这个生存时间是由源主机设置初始值但不是存的具体时间,而是存储了一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

3.四次挥手的抓包

在这里插入图片描述

状态转移图

在这里插入图片描述

三次握手期间可能会收到什么样的攻击?

SYN洪泛攻击

概述:服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
例如
在这里插入图片描述

检测:检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstat 命令来检测 SYN 攻击。

netstat -n -p TCP | grep SYN_RECV 1

常见的防御 SYN 攻击的方法有如下几种:

缩短超时(SYN Timeout)时间
增加最大半连接数
过滤网关防护
SYN cookies技术

引用一篇大佬文章:SYN洪泛攻击

以上是关于三次握手四次挥手总结的主要内容,如果未能解决你的问题,请参考以下文章

TCP三次握手和四次挥手过程

三次握手和四次挥手

总结描述TCP三次握手四次挥手

http三次握手和四次挥手

TCP三次握手四次挥手

三次握手和四次挥手知识总结(超详细)