TCP-三次握手

TCP-三次握手文章目录三次握手三次握手过程详解三次握手的状态变化面试题:四次挥手三次握手简单示意图:客户端–发送带有SYN标志的数据包–一次握手–服务端服务端–发送带有SYN/ACK标志的数据包–二次握手–客户端客户端–发送带有带有ACK标志的数据包–三次握手–服务端SYN同步序列编号(SynchronizeSequenceNumbers):是TCP/IP建立连接时使用的握手信号。在客户机和服务器之间建立正常的TCP网络连接时,客户机首先发出一个SYN消息,服务器使用SYN

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

三次握手

TCP三次握手是浏览器和服务器建立连接的方式,目的是为了使二者能够建立连接,便于后续的数据交互传输。
第一次握手:浏览器向服务器发起建立连接的请求
第二次握手:服务器告诉浏览器,我同意你的连接请求,同时我也向你发起建立连接的请求
第三次握手:浏览器也告诉服务器,我同意建立连接。
至此,双方都知道对方同意建立连接,并准备好了进行数据传输,也知道对方知道自己的情况。接下来就可以传输数据了

简单示意图

一次握手:客户端发送带有 SYN 标志的连接请求数据包给服务端
二次握手:服务端发送带有 SYN+ACK 标志的连接请求和应答数据包给客户端
三次握手:客户端发送带有 ACK 标志的应答数据包给服务端(可以携带数据了)
在这里插入图片描述

详细分析

在这里插入图片描述

0、初始状态:
服务端监听某个端口,处于 LISTEN 状态。

1、客户端发送TCP连接请求
客户端会随机一个初始序列号seq=x(client_isn),
设置SYN=1 ,表示这是SYN握手报文。然后就可以把这个 SYN 报文发送给服务端了,表示向服务端发起连接,之后客户端处于 同步已发送 状态。

2、服务端发送针对TCP连接请求的确认
服务端收到客户端的 SYN 报文后,也随机一个初始序列号(server_isn)(seq=y)
设置ack=x+1, 表示收到了客户端的x之前的数据,希望客户端下次发送的数据从x+1开始。
设置 SYN=1 和 ACK=1。表示这是一个SYN握手和ACK确认应答报文。
最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 同步已接收 状态。

3、客户端发送确认的确认
客户端收到服务端报文后,还要向服务端回应最后一个应答报文
将ACK置为 1 ,表示这是一个应答报文
ack=y+1 ,表示收到了服务器的y之前的数据,希望服务器下次发送的数据从y+1开始。
最后把报文发送给服务端,这次报文可以携带数据,之后客户端处于 连接已建立 状态。
服务器收到客户端的应答报文后,也进入连接已建立 状态

一些思考

为什么要三次握手,而不是两次?

原因主要有两个:
1、主要原因是为了防止历史连接

三次握手时,在网络拥堵等情况下,第一次握手的SYN包迟迟没能发送到服务端,那么客户端会连续发送多次 SYN 建立连接的报文,那么就可能出现一个「旧 SYN 报文」比「最新的 SYN 」 报文早到达了服务端;

那么此时服务端就会回一个 SYN + ACK 报文给客户端;

  • 如果是两次握手连接,就不能判断当前连接是否是历史连接,导致错误。

  • 三次握手时,客户端收到后可以根据自身的上下文,判断这是一个历史连接(序列号过期或超时),那么客户端就会发送 RST 报文给服务端,中止这一次连接。

2、三次握手可以避免资源浪费

如果只有「两次握手」,当客户端的 SYN 请求连接在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN ,

  • 如果是三次握手,第三次握手时服务器可以得到客户端的ack,知道连接已成功建立。
  • 如果没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的 ACK 确认信号,所以每收到一个 SYN 就只能先主动建立一个连接,如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。

SYN 攻击

什么是SYN 攻击?

SYN攻击属于DoS攻击(Denial of Service 拒绝服务)的一种。
SYN攻击大量发送伪造源IP的第一次握手SYN包,服务器每接收到一个SYN包就会为这个连接信息分配核心内存并放入半连接队列,当攻击的SYN包超过半连接队列的最大值时,正常的客户发送SYN数据包请求连接就会被服务器丢弃。导致正常的连接请求无法成功。
严重者引起网络堵塞甚至系统瘫痪。

正常流程:
在这里插入图片描述
当服务端接收到客户端的 SYN 报文时,会将其加入到内核的「 SYN 队列」

接着发送 SYN + ACK 给客户端,等待客户端回应 ACK 报文;

服务端接收到 ACK 报文后,从「 SYN 队列」移入到「 Accept 队列」;

应用从「 Accept 队列」取出连接。

受到 SYN 攻击:
在这里插入图片描述

如何防止SYN 攻击?

1、限制ip连接次数:比如限制同一IP一分钟内新建立的连接数仅为10

2、增大半连接状态的连接数容量
但是增大内存资源占用,不推荐。

3、延迟分配连接资源
当服务器收到第一次握手请求时,不马上分配TCP连接资源。而是计算一个随机值,在第二次握手时传给客户端,当客户端返回第三次握手时,服务器验证随机值的正确性,确认无误才会进入 TCP 的连接状态,才会分配资源。
如果是恶意攻击者发送的大量SYN报文,只要服务器不为其分配资源,也不至于遭到严重破坏了。
在这里插入图片描述

数据包丢失了该怎么办?

1、TCP 第一次握手的 SYN 丢包了,会发生什么?
重传 SYN 数据包,重传次数超过阈值后放弃

2、TCP 第二次握手的 SYN、ACK 丢包了,会发生什么?
客户端 SYN 包没有收到ACK,所以会超时重传
服务端 SYN包也没有收到ACK, 也会超时重传。

3、TCP 第三次握手的 ACK 包丢了,会发生什么?
服务端会一直重传 SYN、ACK 包,重传次数超过阈值后放弃
客户端根据是否开启保活机制分为两种情况:

  • 开启了保活机制的话,会经过 2 小时 11 分 15 秒发现一个「死亡」连接,于是客户端就会断开连接。

  • 没有开启的话,则会一直重传该数据包,直到重传次数超过阈值后就会断开 TCP 连接。

初始序列号为什么随机产生?

为了网络安全
如果不是随机产生初始序列号,黑客将会以很容易的方式获取到你与其他主机之间通信的初始化序列号,并且伪造序列号进行攻击,这已经成为一种很常见的网络攻击手段。

为什么 SYN 段不携带数据却要消耗一个序列号呢?

因为SYN 段需要对方的确认,所以需要占用一个序列号确保这个确认不会出现歧义。如果不占序列号的话,怎么知道这个确认是对数据包的确认还是对syn报文的确认呢?

每次握手可以确定哪些东西?

第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常

第二次握手:Client 确认了自己发送、接收正常,对方发送、接收正常;

第三次握手:Server 确认了自己发送正常,对方接收正常

一个已经建立的 TCP 连接中,客户端中途宕机了,客户端恢复后,向服务端发送SYN包重新建立连接,此时服务端会怎么处理?

我们知道TCP 连接是由「四元组」唯一确认的。
然后这个场景中,客户端的IP、服务端IP、目的端口并没有变化
所以这个问题关键在于:本次连接的源端口是否和上一次连接的源端口相同。
所以分两种情况:

1、不相同
此时服务端会认为是新的连接要建立,于是就会通过三次握手来建立新的连接。

那旧连接里的服务端会怎么样呢?
如果服务端发送了数据包给客户端,由于客户端的连接已经被关闭了,此时客户的内核就会回 RST 报文,服务端收到后就会释放连接。
如果服务端一直没有发送数据包给客户端,在超过一段时间后, TCP 保活机制就会启动,检测到客户端没有存活后,接着服务端就会释放掉该连接。

2、相同
在这里插入图片描述
处于 establish 状态的服务端会回复一个携带了对上次报文的确认号和序列号,这个 ACK 被称之为 Challenge ACK。
接着,客户端收到这个 Challenge ACK,发现序列号并不是自己期望收到的,于是就会回 RST 报文,服务端收到后,就会释放掉该连接。

如何手动关闭一个TCP连接

结论:伪造一个能关闭 TCP 连接的 RST 报文
这个合法的 RST 报文必须同时满足「四元组相同」和「序列号正好落在对方的滑动窗口内」这两个条件。
怎么伪造?
直接伪造符合预期的序列号是比较困难,因为如果一个正在传输数据的 TCP 连接,滑动窗口时刻都在变化,因此很难伪造一个刚好落在对方滑动窗口内的序列号的 RST 报文。
办法还是有的,我们可以伪造一个四元组相同的 SYN 报文,来拿到“合法”的序列号!
怎么拿到?
如果处于 establish 状态的服务端,收到四元组相同的 SYN 报文后,会回复一个 Challenge ACK,这个 ACK 报文里的「确认号」,正好是服务端下一次想要接收的序列号,说白了,就是可以通过这一步拿到服务端下一次预期接收的序列号。
然后用这个确认号作为 RST 报文的序列号,发送给服务端,此时服务端会认为这个 RST 报文里的序列号是合法的,于是就会释放连接!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/186298.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 台式计算机网线,台式电脑连接网线的是哪里 台式电脑怎么连接wifi步骤

    台式计算机网线,台式电脑连接网线的是哪里 台式电脑怎么连接wifi步骤4999或者运营商的问题,方法有哪些,我的笔记本和台式机都是10,联想启天4155,笔记本连的路由器的无线,用(wifi调试桥台式机电脑)使用脚本辅助微连接台式电脑连接信小程序跳一跳简单实用教程新人适用一wifi条龙附带资源,只有网线,另一种可能度出问题了,28访问量,什么叫做二次开发,惠普连接暗影精台式电脑连接灵5,连接对于家中台式电脑连接路由电脑怎样器还有连wifi接猫的用户,台式电脑,热门台…

  • API开发的版本控制技巧

    API开发的版本控制技巧

  • SpringBoot图片验证码

    SpringBoot图片验证码“原生js+SpringBoot+hutool工具”实现浏览器验证码功能,点击可刷新。

    2022年10月16日
  • 集合:映射,单射,满射,双射

    集合:映射,单射,满射,双射这些概念太重要了,虽然很不起眼,但是几乎所有地方都要用,一旦不清楚,会对一个问题审视错误。集合:元素汇聚在一起,就构成了一个集合。假设有集合A和集合B。映射:将A中的每一个元素,根据一个规则,对应到B中的一个元素去,比如A中是一些儿女,B中是他们的父亲,那么每一个A中的元素都可以对应到B中的唯一一个元素,这就是一种规则,即映射。因为一个人的爸爸只有一个,但是反之未必,因为一个爸爸可能有多个儿女。我们发现,这个和函数的概念非常相似,集合A相当于定义域,映射相当于f。但是集合的概念更加宽泛,正如前面所有

  • JAVA生成uuid_oracle随机生成uuid

    JAVA生成uuid_oracle随机生成uuidUUID生成importjava.util.UUID;publicclassJavaUUIDTest{publicstaticvoidmain(String[]args){//未加工的UUIDStringpreUuid=UUID.randomUUID().toString();System.out.println(preUuid);//第一种方法生成UUID,去掉“-”符号

  • python numpy矩阵转置_python转制

    python numpy矩阵转置_python转制题目难度:★☆☆☆☆类型:几何、二维数组、数学给定一个矩阵A,返回A的转置矩阵。矩阵的转置是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引。示例示例1输入:[[1,2,3],[4,5,6],[7,8,9]]输出:[[1,4,7],[2,5,8],[3,6,9]]示例2输入:[[1,2,3],[4,5,6]]输出:[[1,4],[2,5],[3,6]]提示1…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号