46、TCP的“三次握手”

在上一节中,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.mzph.cn/news/67884.shtml

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

相关文章

Spring MVC 五 - DispatcherServlet初始化过程(续)

今天的内容是SpringMVC的初始化过程,其实也就是DispatcherServilet的初始化过程。 Special Bean Types DispatcherServlet委托如下一些特殊的bean来处理请求、并渲染正确的返回。这些特殊的bean是Spring MVC框架管理的bean、按照Spring框架的约定处理相关请求&…

leetcode56. 合并区间(java)

合并区间 题目描述贪心算法代码演示 题目描述 难度 - 中等 leetcode56. 合并区间 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好…

Elasticsearch 对比传统数据库:深入挖掘 Elasticsearch 的优势

当你为项目选择数据库或搜索引擎时,了解每个选项的细微差别至关重要。 今天,我们将深入探讨 Elasticsearch 的优势,并探讨它与传统 SQL 和 NoSQL 数据库的比较。 1. Elasticsearch简介 Elasticsearch 以强大的 Apache Lucene 库为基础&#…

算法通关村第9关【白银】| 二分查找与搜索树高频问题

基于二分查找的拓展问题 1.山脉数组的峰顶索引 思路&#xff1a;二分查找 山峰有三种状态&#xff1a;需要注意数组边界 1.顶峰&#xff1a;arr[mid]>arr[mid1]&&arr[mid]>arr[mid-1] 2.上坡&#xff1a;arr[mid]<arr[mid1] 3.下坡&#xff1a;arr[mid]…

l8-d6 socket套接字及TCP的实现框架

一、socket套接字 /*创建套接字*/ int socket(int domain, int type, int protocol); /*绑定通信结构体*/ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); /*监听套接字*/ int listen(int sockfd, int backlog); /*处理客户端发起的连接&#xff0…

智能合约安全,著名的区块链漏洞:双花攻击

智能合约安全&#xff0c;著名的区块链漏洞&#xff1a;双花攻击 介绍: 区块链技术通过提供去中心化和透明的系统彻底改变了各个行业。但是&#xff0c;与任何技术一样&#xff0c;它也不能免受漏洞的影响。一个值得注意的漏洞是双花攻击。在本文中&#xff0c;我们将深入研究…

【数据结构练习】栈的面试题集锦

目录 前言&#xff1a; 1.进栈过程中可以出栈的选择题 2.将递归转化为循环 3.逆波兰表达式求值 4.有效的括号 5. 栈的压入、弹出序列 6. 最小栈 前言&#xff1a; 数据结构想要学的好&#xff0c;刷题少不了&#xff0c;我们不仅要多刷题&#xff0c;还要刷好题&#x…

16-MyCat

一 Mycat概述 1 什么是Mycat 什么是Mycat Mycat是数据库中间件&#xff0c;所谓数据库中间件是连接Java应用程序和数据库中间的软件。 为什么要用Mycat 遇到问题&#xff1a; Java与数据库的紧耦合高访问量高并发对数据库的压力读写请求数据不一致 2 Mycat与其他中间件区别 目…

【USRP】调制解调系列6:16APSK、32APSK 、基于labview的实现

APSK APSK是&#xff0c;与传统方型星座QAM&#xff08;如16QAM、64QAM&#xff09;相比&#xff0c;其分布呈中心向外沿半径发散&#xff0c;所以又名星型QAM。与QAM相比&#xff0c;APSK便于实现变速率调制&#xff0c;因而很适合目前根据信道及业务需要分级传输的情况。当然…

分布式环境下的数据同步

一般而言elasticsearch负责搜索&#xff08;查询&#xff09;&#xff0c;而sql数据负责记录&#xff08;增删改&#xff09;&#xff0c;elasticsearch中的数据来自于sql数据库&#xff0c;因此sql数据发生改变时&#xff0c;elasticsearch也必须跟着改变&#xff0c;这个就是…

jmeter调试错误大全

一、前言 在使用jmeter做接口测试的过程中大家是不是经常会遇到很多问题&#xff0c;但是无从下手&#xff0c;不知道从哪里开始找起&#xff0c;对于初学者而言这是一个非常头痛的事情。这里结合笔者的经验&#xff0c;总结出以下方法。 二、通过查看运行日志调试问题 写好…

STM32存储左右互搏 I2C总线读写FRAM MB85RC16

STM32存储左右互搏 I2C总线读写FRAM MB85RC16 在较低容量存储领域&#xff0c;除了EEPROM的使用&#xff0c;还有铁电存储器FRAM的使用&#xff0c;相对于EEPROM, 同样是非易失性存储单元&#xff0c;FRAM支持更高的访问速度&#xff0c; 其主要优点为没有EEPROM持续写操作跨页…

Python虚拟环境venv下安装playwright介绍及记录

playwright介绍 Playwright是一个用于自动化Web浏览器测试和Web数据抓取的开源库。它由Microsoft开发&#xff0c;支持Chrome、Firefox、Safari、Edge和WebKit浏览器。Playwright的一个主要特点是它能够在所有主要的操作系统&#xff08;包括Windows、Linux和macOS&#xff09…

计算机毕设 大数据商城人流数据分析与可视化 - python 大数据分析

文章目录 0 前言课题背景分析方法与过程初步分析&#xff1a;总体流程&#xff1a;1.数据探索分析2.数据预处理3.构建模型 总结 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到…

SMU200A/罗德与施瓦茨SMU200A信号发生器

181/2461/8938产品概述 R&S SMU200A信号发生器旨在满足现代通信系统研发及其生产中遇到的所有要求。R&S SMU200A矢量信号发生器不仅将多达两个独立的信号发生器组合在一个只有四个高度单位的机柜中&#xff0c;还提供无与伦比的RF和基带特性。 Rohde & Schwarz S…

Vue3数值动画(NumberAnimation)

效果如下图&#xff1a;在线预览 APIs 参数说明类型默认值必传from数值动画起始数值number0falseto数值目标值number1000falseduration数值动画持续时间&#xff0c;单位msnumber3000falseautoplay是否自动开始动画booleantruefalseprecision精度&#xff0c;保留小数点后几位…

NineData 中标移动云数据库传输项目

导读近日&#xff0c;玖章算术 NineData 智能数据管理平台成功中标《2023 年移动云数据库传输服务软件项目》&#xff0c;中标金额为 406 万。这标志着玖章算术 NineData 平台已成功落地顶级运营商行业&#xff0c;并在数据管理方面实现了大规模应用实践。 NineData 中标 2023 …

SQLite简单介绍

一.简单介绍 SQLite是一款轻型的数据库&#xff0c;是遵守ACID的关系型数据库管理系统&#xff0c;它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的&#xff0c;而且已经在很多嵌入式产品中使用了它&#xff0c;它占用资源非常的低&…

音频基础知识

文章目录 前言一、音频基本概念1、音频的基本概念①、声音的三要素②、音量与音调③、几个基本概念④、奈奎斯特采样定律 2、数字音频①、采样②、量化③、编码④、其他相关概念<1>、采样位数<2>、通道数<3>、音频帧<4>、比特率&#xff08;码率&#…

02-Flask-对象初始化参数

对象初始化参数 前言对象初始化参数import_namestatic_url_pathstatic_foldertemplate_floder 前言 本篇来学习Flask中对象初始化参数 对象初始化参数 import_name Flask程序所在的包(模块)&#xff0c;传__name__就可以 _name_ 是一个标识 Python 模块的名字的变量&#x…