46、TCP的“三次握手”

news2024/11/26 2:46:48

在上一节中,TCP首部常用的几个选项,有些选项的参数就是在通信双方在建立TCP连接的时候进行确定和协商的。所以在学习过TCP报文首部之后,下面我们开始学习TCP的连接建立。

TCP的一个特点是提供可靠的传输机制,还有一个特点就是TCP是面向连接的面向连接意思就是说,在进行数据的传输之前,先要建立连接,再传输数据,传输完毕之后再释放连接。在这个过程中,要保证可靠传输的话,建立连接需要通信双方进行“三次握手”,数据传输中由一些TCP的可靠机制来保证,释放连接需要通信双方进行“四次挥手”。我们按顺序学习,这一节先学习建立连接的“三次握手”过程。

“三次握手”这是一个比较传统的名称,也是业内用的最广泛的说法。但这个说法并不太准确,谢希仁教授的最新一版的教材中指出更准确的说法应该是“三报文握手”,因为通信双方建立TCP连接时相互交换了三个报文,而不是三次。不过,为了贴合业内已被广泛使用的说法,所以本文还是使用“三次握手”这个称呼。


“三次握手”的过程

为了更清楚的说明这个过程,所以我们在这里学习的时候,最好带入一个情景,最典型的就是“C/S情景”也就是“客户—服务器”情景。客户是请求服务的,服务器是提供服务的,带入这个情景可以更好的理解整个交互过程,而且TCP建立连接使用的就是“客户—服务器”的方式。

不过,要注意的是:“客户—服务器”这里指的是一种比较抽象的概念,我们前面讲两台主机之间的通信实际上就是两个应用进程之间的通信。所以我们就这样想:请求服务的一方,它的进程需要主动发起连接,而提供服务的一方,它的进程要等待连接建立。主动发起连接的就是客户进程,等待连接建立的就是服务器进程。

带入这个情景之后,“三次握手”的过程理解起来也就比较容易了:

使用教材上比较经典的例子来说明:

在上面这个图中,客户方是主机A的一个进程,服务器方是主机B的一个进程。(为了方便叙述,以下简述为客户A、服务器B)

图中的“CLOSED”、“LISTEN”、“SYN-SENT”等等,这些代表的是TCP的连接状态,表明当前这个TCP连接处在哪个步骤。

第一次握手

一开始,客户A和服务器B都是处于“CLOSED”状态,也就是关闭状态。客户A主动发起TCP建立连接请求,也就是向服务器B发送一个报文段,在这个报文段中“SYN”控制位设置为1,表明“同步位有效”,并选择一个随机数 x 作为序号,发送完毕之后客户A进入“SYN-SENT”(同步已发送)状态。同时,服务器B由于是等待连接建立,所以是进入“LISTEN”(监听)状态,等待来自客户端的连接建立请求。

第二次握手

接收到客户端的连接建立请求后,服务器B进入“SYN-RCVD”(同步已收到)状态,并向客户A发回一个确认报文。在这个确认报文中,同样要把“SYN”位设置为有效,同时选择一个新的随机数 y 作为确认报文的序号。另外,由于这是确认报文,所以必须把“ACK”位也设置为有效,并选择“x+1”作为确认号

在这里,我们就可以注意到一个问题了。为什么确认号是“x+1”呢?

我们前面讲过,确认号的意思是:期望收到对方的下一个报文的序号。客户A发送建立请求的时候,序号设置为了 x ,服务器B发回确认的时候,把确认号设置为了x+1,这就说明服务器B期望收到客户A下一次发来序号为“x+1”的报文段。

这就透露给我们一个细节:第一次握手的时候,客户A发出去的报文段是不携带数据的,也就是这个报文段的数据部分是0字节

第三次握手

客户A收到对方的确认报文之后,还要向对方发送一个“确认的确认”。在这个“确认的确认”报文中,SYN位不需要有效了,因为双方已经完成同步了,ACK位必须有效,因为还要使用确认号。值得注意的是:seq值,也就是序号需要设置为“x+1”,因为对方期望我发送的下一个报文段的序号是“x+1”,你期望这个,我就发给你这个;同理,这个ack值,也就是确认号要设置为“y+1”,因为刚才对方发来的序号是y,所以我期望你下一次发来序号为“y+1”的报文段。

由此可见,第二次握手和第一次握手一样,都是不携带数据的

第三次握手的报文发出去之后,客户A进入“ESTABLISHED”(连接已建立)状态,服务器B收到后,同样进入(连接已建立)状态,TCP连接建立成功。

不过从图中,我们可以看到,第三次握手的报文在发送过程中,可以进行数据传送。这个是可以的,第三次握手的报文是可以携带数据的

现在,又有一个问题,为什么必须是三次握手呢?看下面的情况:

假设,A发送连接建立请求,但是很不巧,当时这个报文“走”的网络路径比较拥堵,导致这个报文在路上某一个路由器上长时间滞留。所以A在超时定时器到期之时,重传了这个请求,这次与服务器B成功建立了TCP连接,传输数据完毕后释放了连接。这时,第一次发出去的建立请求报文又恰好到达了B,这时B就会认为这是一个新的连接,所以B发送出确认,A收到确认后发现这是一个对已经失效的请求报文的确认,所以A不会理睬这个确认,更不会给B发出“确认的确认”,这个连接也就建立不起来,不会白白浪费资源。

最后,需要说明的是:我们在这里只学习了TCP建立连接“三次握手”的最基本也是最必须的设置。当前具体情况中也会有一些其它的设置,比如双方在建立连接时选择是否“窗口缩放”选项、将MSS值设置为多少等选项。


本节我们学习了TCP建立连接的“握手”过程,从下面一节开始将学习数据传输过程中TCP是怎么保证可靠的,包括:TCP的流量控制、拥塞控制、基于滑动窗口的可靠传输等知识。

参考教材:谢希仁《计算机网络》第八版

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/969723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

字符型注入([SWPUCTF 2021 新生赛]easy_sql)

拿到题目,查看源码,可知是要输入参数wllm。 输入参数/?wllm1,得到会显 继续输入参数/?wllm1,报错,确定为字符型漏洞 1.查看字段列表,发现在字段4报错,确定为3列 ?wllm-1 order by 3-- ?wl…

基于JavaScript粒子流动效果

这是一个HTML文件,主要包含了一些CSS样式和JavaScript代码,用于创建一个动画效果。 在CSS部分,定义了一些基本的样式,包括页面的背景颜色、位置、大小等。特别的,定义了两种球形元素(.ball_A 和 .ball_B&am…

静态路由配置实验:构建多路由器网络拓扑实现不同业务网段互通

文章目录 一、实验背景与目的二、实验拓扑三、实验需求四、实验解法1. 配置 IP 地址2. 按照需求配置静态路由,实现连接 PC 的业务网段互通 摘要: 本实验旨在通过配置网络设备的IP地址和静态路由,实现不同业务网段之间的互通。通过构建一组具有…

nginx-基于range做断点续传

nginx默认开启了range断点续传,只要再请求时载请求头上添加header,range,nginx就可以根据range范围返回相应的字节。

zabbix配置钉钉告警

钉钉告警python脚本 cat python20 #!/usr/bin/python3 #coding:utf-8 import requests,json,sys,os,datetime # 机器人的Webhook地址 webhook"钉钉" usersys.argv[1] textsys.argv[3] data{"msgtype": "text","text": {"conten…

Leetcode 2431.最小偶倍数

给你一个正整数 n ,返回 2 和 n 的最小公倍数(正整数)。 示例 1: 输入:n 5 输出:10 解释:5 和 2 的最小公倍数是 10 。示例 2: 输入:n 6 输出:6 解释&#…

docker 笔记10:Docker轻量级可视化工具Portainer

1. 是什么 Portainer 是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。 2.安装 https://docs.portainer.io/v/ce-2.9/start/install/server/docker/linux 步骤 docker命令安装 docker run -d …

【postgresql 基础入门】数据库服务的管理

数据库服务管理 ​专栏内容: postgresql内核源码分析手写数据库toadb并发编程 ​开源贡献: toadb开源库 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤&#xff…

第一章:绪论

1.1 系统架构概述 架构是体现在组件中的一个系统的基本组织、它们彼此的关系与环境的关系以及指导它的设计和发展的原则。 系统是组织起来完成某一特定功能火一组功能的组件集。系统这个术语包括了单独的应用程序、传统意义上的系统、子系统、系统之系统、产品线、整个企业及…

三层交换实验:实现不同VLAN间的互通与路由配置

文章目录 一、实验背景与目的二、实验拓扑三、实验需求四、实验解法1. PC 配置 IP 地址2. PC2 属于 Vlan10,PC3 属于 Vlan20,在三层交换机上配置 Vlanif 三层接口实现 Vlan10 和 Vlan20 三层互通3. 测试在 PC3 上 Ping PC4 ,可以 Ping 通 PC4…

吴恩达《面向开发者的提示词工程》

Ref: 【中英字幕 | P01 Introduction】2023吴恩达新课《面向开发者的提示词工程》_哔哩哔哩_bilibili 对应的笔记 ChatGPT Prompt - 知乎 本课程主要介绍指令微调LLM的最佳实践 在大型语言模型或LLM的开发中,大体上有两种类型的LLM,我将其…

kotlin协程广播管道BroadcastChannel,订阅管道openSubscription

kotlin协程广播管道BroadcastChannel&#xff0c;订阅管道openSubscription import kotlinx.coroutines.* import kotlinx.coroutines.channels.*fun main(args: Array<String>) {//广播消息//也可以把普通Channel转换成广播Channel//val channel Channel<Int>()/…

企业场景篇

企业场景篇 设计模式 简单工厂模式 工厂&#xff08;factory&#xff09;处理创建对象的细节&#xff0c;一旦有了SimpleCoffeeFactory&#xff0c;CoffeeStore类中的orderCoffee()就变成此对象的客户&#xff0c;后期如果需要Coffee对象直接从工厂中获取即可。这样也就解除了…

【javaweb】学习日记Day9 - Mybatis 基础操作

目录 一、删除 &#xff08;1&#xff09;在mapper接口执行sql删除语句 ① 注解后sql语句没有提示怎么办&#xff1f; &#xff08;2&#xff09;测试层 &#xff08;3&#xff09;开启mybatis日志 &#xff08;4&#xff09;预编译SQL 二、新增 &#xff08;1&#…

深入探讨Java虚拟机(JVM):执行流程、内存管理和垃圾回收机制

目录 什么是JVM&#xff1f; JVM 执行流程 JVM 运行时数据区 堆&#xff08;线程共享&#xff09; Java虚拟机栈&#xff08;线程私有&#xff09; 什么是线程私有? 程序计数器&#xff08;线程私有&#xff09; 方法区&#xff08;线程共享&#xff09; JDK 1.8 元空…

Linux下 Socket服务器和客户端文件互传

目录 1.项目描述 2.函数准备 2.1 gets函数 2.2 popen函数、fread函数 2.3 access 函数 2.4 exit 函数 2.5 strtok 函数 2.6 chdir函数 3.项目代码 3.1服务器代码 3.2客户端代码 4.问题总结 1.项目描述 基于Soket聊天服务器&#xff0c;实现服务器和客户端的文件传输。…

机器学习——线性回归/岭回归/Lasso回归

0、前言&#xff1a; 线性回归会用到python第三方库&#xff1a;sklearn.linear_model中的LinearRegression导入第三方库的方法&#xff1a;from sklearn.linear_model import LinearRegression使用LinearRegression(二维数据&#xff0c;一维数据)进行预测&#xff0c;其中数…

YOLOv5,v8中文标签显示问题

本人使用的是YOLOv5-7.0&#xff0c;YOLOv8的最新版本 1. 训练YOLOv5时matplotlib无法显示中文标签 数据集中的标签是中文&#xff0c;在训练YOLOv5&#xff0c;v8算法时&#xff0c;matplotlib库无法显示中文 2 解决方法 在yolov5/utils/plots.py文件中手动添加黑体字体&a…

flutter Could not get unknown property ‘ndkVersion’

使用的 flutter 版本为 3.7.2 &#xff0c;编译运行 如下 Could not get unknown property ‘ndkVersion’ for object of type com.android.build.gradle.internal.dsl.BaseAppModuleExtension 解决方法是 在flutter-3.7.2\packages\flutter_tools\gradle\flutter.gradle配置…

Java特性之设计模式【抽象工厂模式】

一、抽象工厂模式 概述 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式 在抽象工厂模式中&#xff0c;接口是…