当前位置: 首页 > article >正文

【网络通信基础与实践番外三】TCP的三次握手和四次挥手和例题

一、TCP连接的三次握手

第一次握手:客户端首先向服务器发送一个特殊的TCP报文,这个报文段首部不包含应用层数据,但是在报文段中有一个SYN标志位被置1。因此这个特殊的报文段也被叫做SYN报文段,然后客户端随机选择一个初始序列号(client_isn),并将此数字放入初始TCP SYN段的序列号字段中,SYN段又被封装到IP数据段中发送给服务器。

第二次握手:一旦包含IP数据段到达服务器后,服务端会从IP数据段中提取TCP SYN段,将TCP缓冲区和变量分配给连接,然后给客户端发送一个连接所允许的报文段,这个连接所允许的报文段不包括应用层数据,包括了SYN =1, TCP报文段的首部确认号被设置为client_isn+1,服务器选择自己的初始序号(server_isn),然后放到报文中。

第三次握手:在收到SYNACK报文段后,客户端也要为该连接分配缓冲区和变量。客户端主机向服务器发送另一个报文段,最后一个报文段对服务器发送的响应报文做了确认,确认的标准是客户端发送的数据段中确认号为server_isn+1,因为连接已经建立,SYN = 0。 

1、SYN泛洪攻击

在这里开始服务器为了响应一个收到的SNY,分配并初始化变量连接和缓存,然后服务器发送一个SYNACK作为响应,然后等待来自于客户端的ACK报文。如果客户端不发送ACK来完成最后一步的话,那么这个连接就处在一个挂起的状态,也就是半连接的状态。

攻击者通常在这种情况下(第二次握手完毕第三次握手没完成)发送大量的TCO SYN报文段,服务端持续相应,但是每次连接都完不成三次握手的步骤。随着SYN的不断增加,服务器会不停地为这些半开连接分配资源,导致服务器的连接最终被消耗殆尽。

抵御这种攻击的方法使用SYN cookie,当服务器收到SYN报文段时,它并不知道这个报文段来自哪里,是来自攻击者主机还是正常客户端的主机。因此服务器并不会分配资源,也不会生成一个半开连接。与此相反,服务器生成一个初始的TCP序列号,这个序列号是SYN报文段的源和目的IP地址与端口号这个四元组构造的一个复杂的散列函数,这个散列函数生成的TCP序列号就是SYN cookie,用于缓存SYN请求。然后服务器会发送带着SYN Cookie的SYNACK分组,有一点注意的是服务器不会记忆这个cookie或者SYN的其他状态信息。

如果发送方不是攻击者的话,它就会返回一个ACK报文段,当服务器收到这个ACK后,需要验证这个ACK与SYN发送的是否相同,验证的标准就是散列函数是否匹配。

如果发送方没有返回ACK,就认为是攻击者,那么这样也没关系,因为服务器没有收到ACK,不会分配变量和缓存资源,不会对服务器产生危害。

2、为什么两次握手不可以?

防止已经失效的报文在双方连接已经释放了的情况下突然又传送到了服务器,从而让服务端误认为要进行第二次握手,但是客户端已经释放连接了面对服务器的第二次握手请求不会理睬,服务端的资源被浪费。

二、TCP释放的四次挥手

第一次挥手:客户端和服务器开始都处于ESTABLISHED状态,客户端应用程序发出释放连接的报文段,并停止发送数据,主动关闭TCP连接。客户端主机发送释放连接的报文段,报文段中首部FIN位置为1,不包含数据,序列位号seq=u,客户端主机进入到FIN-WAIT-1(终止等待1)阶段。

第二次挥手:服务器主机接收到客户端发出的报文段后,即发出确认应答报文,确认应答报文中ACK=1,生成自己的序号位seq=v,ack=u+1,然后服务器主机CLOSED-WAIT(关闭等待)状态,这个时候客户端-->服务器这条方向的连接就释放了,客户端没有数据需要发送,此时服务器是一种半连接的状态,但是服务器主机仍然可以发送数据。客户端主机收到服务端主机的确认应答后,即进行FIN-WAIT-2(终止等待2)的状态,等待服务器发出连接释放的报文段。

第三次挥手:当服务器主机没有数据发送后,应用进程就会通知TCP释放连接。这时服务器主机就会发出断开连接的报文段,报文段中ACK=1,序列号seq=w,因为在客户端FIN-WAIT-2阶段服务端可能已经发送了一些数据,因此seq不一定等于v+1,在发送完断开请求的报文后服务端主机就进入了LAST-ACK(最后确认)阶段。

第四次挥手:客户端收到服务端的断开连接请求后,客户端需要作出响应,客户端发出断开连接的报文段,此报文段中ACK=1,序列号seq=u+1,因为客户端从连接开始断开后就没有再发送数据,ack=w+1,然后进入到TIME-WAIT(时间等待)状态,但是这个时候TCP连接没有释放。必须经过2MSL(最长报文段寿命 Maximum Segment Lifetime )后,客户端才会进入到CLOSED状态。

为什么要等待2MSL呢?

当然是我们传输过程中最常见的两个问题:一个是丢包一个是无效包。

一个理由是最后一个由客户端向服务端发送到ACK报文段可能会丢失,从而使服务端一直处于LAST-ACK状态等待客户端响应。这个时候服务端会重传一次FIN ACK断开连接报文,客户端接收后再重新确认,重启定时器。如果客户端不是2MSL,在客户端发送ACK后直接关闭的话,如果报文丢失,那么双方主机会无法进入到CLOSED状态。

另一个理由是防止已经失效的报文段。客户端在发送一个ACK后,再经过2MSL,就可以使本连接持续时间内所产生的报文段都从网络中消失。从而保证在关闭连后不会有还在网络中滞留 的报文段去骚扰服务器。

三、例题

其实本质上在考察连接过程中三次握手最后一次握手的序列号和释放过程中第一次挥手时序列号二者的差值。

TCP连接过程:

 

TCP释放过程: 

 

 


http://www.kler.cn/news/334513.html

相关文章:

  • Java.数据结构.HashSet
  • 【go入门】运算符
  • 【Java并发编程的艺术3】Java内存模型(上)
  • Redis: 集群高可用之MOVED转向和ASK转向解决方案
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-01
  • LeetCode讲解篇之98. 验证二叉搜索树
  • PCIe6.0 AIC金手指和板端CEM连接器信号完整性设计规范
  • Nexus制品库搭建(maven)
  • 汇编语言笔记2
  • java数据类型转换和注释
  • esp8266 at指令链接wifi时一直connect disconnest
  • 信号用wire类型还是reg类型定义
  • 2024年,现在做全职的AI产品经理,时机对不对?
  • VMware ESXi更改https的TLS协议版本
  • 植物叶片病害检测数据集 5100张 29类 带标注 voc yolo
  • 利用 Python 爬虫采集 1688商品详情
  • 【D3.js in Action 3 精译_028】3.4 小节 DIY 实战:使用 Observable 在线绘制 D3 条形图
  • 问:TCP长连接vs短连接有哪些差异?
  • Unity MVC框架演示 1-1 理论分析
  • VSCode python代码颜色调整与pycharm对齐