TCP/IP协议 - 三次握手四次挥手(入门易懂版)_6、三次握手、四次挥手-程序员宅基地

技术标签: 网络  三握四挥  网络协议  tcp/ip  

握手通俗理解为两个人见面Say Hai,客户端和服务端建立连接

挥手就可以理解为两个人结束会面,要Say Goodbai,客户端和服务端断开连接

        要了解什么是三握四挥,必须要了解一个重要的知识点:什么是TCP报文格式,也就是三握四挥中传送的内容是什么,遇到什么格式才能触发服务端和客户端的交流。

TCP报文格式

        TCP报文是TCP层传输的数据单元,也叫报文段

 从上向下依次来看:

1.端口号:用来标识同一台计算机的不同的应用进程,比如熟悉的80端口,3306端口

1)源端口:源端口和IP地址是标识报文的返回地址

2)目的端口:端口指明接收方计算机上的应用程序接口

TCP报头中的源端口号目的端口号同IP数据报中的源IP目的IP唯一确定一条TCP连接

2.序号和确认号:是TCP可靠传输的关键部分

1)序号:seq(4字节 = 32位)每一个报文都有自己的序号,这个是根据计算机自动生成的,用来唯一标识当前报文。在TCP传送的流中,每一个字节一个序号。

        比如:一个报文段的序号为 300,此报文段数据部分共有 100 字节,则下一个报文段的序号为 400 。所以序号确保了 TCP 传输的有序性

2)确认序号:(4字节 = 32位)一般用小写 ack 表示,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到

3.数据偏移/首部长度:4bits,用来表示报文首部的长度

        由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。

4.保留:6bits,为将来定义新的用途保留,一般置0

5.标志位:URG  ACK  PSH  RST  SYN  FIN,共6个,每个标志位为 1 bit,每一个标志位表示一个控制功能

1)URG:紧急指针标志,为 时表示紧急指针有效,为 则忽略紧急指针。

2)ACK确认序号标志,为 1 时表示确认号有效,为 0 表示报文中不含确认信息,忽略确认号字段。

3)PSH:push 标志,为 1 表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。

4)RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。

5)SYN同步序号,用于建立连接过程,在连接请求中,SYN = 1 和 ACK = 0 表示该数据段没有使用捎带的确认域,SYN = 1 和 ACK = 1 为连接应答捎带一个确认 。

6)FINfinish 标志,用于释放连接,为 1 时表示发送方已经没有数据发送了,即关闭本方数据流。

6.窗口:滑动窗口大小

        用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小时一个16bit字段,因而窗口大小最大为65535。

7.校验和:奇偶校验

        此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。

8.紧急指针:只有当 URG 标志置 1 时紧急指针才有效。

        紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。

9.选项和填充:最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size)

        每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。

10、数据部分: TCP 报文段中的数据部分是可选的。

在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

三次握手

便于理解图:

 实际:

        TCP协议是传输层的一个面向连接的安全可靠的传输协议,三次握手的机制是保证能建立一个安全可靠的连接。

  • 那么第一次握手是由客户端发起,客户端会向服务端发送一个报文,在报文里 SYN = 1 ,当服务端收到这个报文之后,就知道客户端要和我发起一个新的连接。
  • 于是,服务端就向客户端发送一个确认消息报这便是第二次握手,这个消息报文 ACK = 1 。

        (为什么两次握手不行?)以上两次握手之后,对于客户端来说已经知道,我既能给服务端发消息也能收到服务端发的消息,但是对于服务端来说,两次握手是不够的,因为,到目前为止,服务端只知道一件事情,客户端发给我的消息我能收到,我发给客户端的消息能不能收到不能确认。

  • 所以还需要进行第三次握手,当客户端收到服务端发来的确认消息的报文之后,还要继续给服务端发消息确认,也是一个 ACK = 1 确认消息报。

        通过以上三次连接,不管是客户端还是服务端,都能确认我既能给对方发消息,也能收到对方的消息,那么这个连接可以被安全的建立。

四次挥手

便于理解图:

 实际图:

  • 四次挥手也是客户端发起的,客户端会发送一个报文,报文 FIN = 1 。
  • 客户端收到这个报文之后,就知道了客户端想要和我断开连接,但是此时服务端不一定做好准备,因为当客户端发起断开连接的报文的时候,服务端有可能还有未发送完的报文消息需要继续发送,所以此时服务端只能告诉客户端我知道你要和我断开连接了,但是我这里可能还没做好准备,需要等我一下,等会我会告诉你,于是,发完这个消息确认报之后。
  • 稍过片刻之后服务端继续发送一个断开连接的报文FIN = 1 ,表明服务端已经做好断开连接的准备,那么,当这个消息发给客户端的时候。
  • 客户端同样需要继续发送一个消息确认的报文,那么通过这四次的相互沟通和连接,我就知道了,不管是客户端还是服务端,都已经做好了断开的准备。这是我对三次握手四次挥手的理解。

三握四挥疑点:

为什么不是两次握手?

        因为在这两次握手之后,对于客户端来说,发送和接收都没有问题,但是对于服务器,只知道接受没有问题,发送的消息客户端有没有收到,服务器是不知道的,因此需要第三次握手,第三次握手保证了客户端和服务端既能给对方发送消息,又能响应对方。

为什么不是四次握手?

        这是两种情况,第一种是把服务器的确认ACK和连接SYN分两次发送,这种在理论上是可行的,就好比

服务器:我在
服务器:你在吗?

但是一次性能干完的事情,非分两次,太浪费资源了。
第二种情况就是客户端再次发送确认消息,也是同理,三次握手就已经保证了双方的连接是可靠的,客户端再确认也是浪费资源

为什么不是三次挥手,是四次挥手?

        当客户端发送断开请求给服务端时(第一次挥手),服务端首先应该回复客户端确认收到(第二次挥手),但此时不确定服务端是否准备好(是否有未处理完的消息),所以应该等服务端处理好之后,再发送断开消息给客户端,告诉客户端已经准备好断开了(第三次挥手),这样客户端收到消息就会知道服务端已经准备好,可以断开,但此时客户端要给服务端发送确认收到的消息(第四次挥手),这样便确保了整个挥手断开过程顺利进行。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/DEGv587/article/details/122682319

智能推荐

Cocos2d-x 窗口大小调整_cocos2dx设置窗口大小-程序员宅基地

文章浏览阅读4.2k次。打开src目录下的AppDelegate.cpp文件,若无修改则在第45行处找到全局声明的Size变量,修改`designResolutionSize`中的大小即可。_cocos2dx设置窗口大小

springboot接收枚举值的默认方式_springboot get请求怎么接收前端传递的枚举数字-程序员宅基地

文章浏览阅读1.6k次。测试代码:@PostMapping() public void test(@RequestBody Student student){ System.out.println(student.getLover().name()); }class Student{ private Lover lover; public Lover getLover() { return lover; } public void setLover_springboot get请求怎么接收前端传递的枚举数字

【数学建模笔记】【第七讲】多元线性回归分析(二):虚拟变量的设置以及交互项的解释,以及基于Stata的普通回归与标准化回归分析实例_stata两个虚拟变量的交互项-程序员宅基地

文章浏览阅读1.5w次,点赞24次,收藏120次。简单来说就是去量纲后的回归(因为你要比较不同变量之间的显著性的大小,那么带着量纲怎么比,所以先把量纲去掉,然后再比较)官话:为了更为精准的研究影响评价量的重要因素(去除量纲的影响),我们可考虑使用标准化回归系数。_stata两个虚拟变量的交互项

mysql-程序员宅基地

文章浏览阅读203次。有时候安装mysql后使用mysql命令时报错 Can't connect to MySQL server on localhost (10061),或者用net start mysql 时报服务名无效,一般是因为mysql服务没有启动。这时候可以用管理身份运行cmd.exe(注意必须是管理..._c:\program files\mysql\mysql server 5.6\bin>mysqld --install install/remove

亚信科技java笔试题答案_亚信笔试题卷以及答案.docx-程序员宅基地

文章浏览阅读6.2k次,点赞3次,收藏44次。亚信联创科技校园招聘B 卷考试时间60_分钟 _考试方式(闭)卷(本试卷满分 100 分,答案请写在答题卡上)请不要在问卷上答题或涂改,笔试结束后请务必交回试卷部分内容分值备注一、计算机基础40分C/C++语言基础40分技能部分二、二选一JAVA 语言基础40分三、数据库20分总分100 分第一部分——计算机基础一、选择题(每题 2 分,总分 40分)1.CPU 状态分为目态和管态两种..._亚信科技java实习笔试题

三线城市程序员的薪资待遇怎么样?我分享提高java技术水平的几个方法_三线城市学java-程序员宅基地

文章浏览阅读1.3k次。3年对一个程序员来说是非常重要的。像我自己本身就是做程序员的,目前的薪资待遇是13K左右,虽然在我所在的公司不是最高的,但在所在的这个城市的消费水平来说,除了日常的开支,包括房租、水电、伙食、人际交往等费用之外,还能留下一部分闲钱自己存起来。不同城市的薪资待遇是不一样的,这主要是由于当地的消费水平和经济发展水平不同,所以如果你想要更高的薪资待遇,就要考虑在一线城市或者经济发达的城市工作。一个有着丰富工作经验的程序员,他的技能水平、经验和能力都比没有经验的程序员更加出色,所以他们的薪资待遇也会更高一些。_三线城市学java

随便推点

恭迎万亿级营销(圈人)潇洒的迈入毫秒时代 - 万亿user_tags级实时推荐系统数据库设计...-程序员宅基地

文章浏览阅读418次。标签PostgreSQL , 标签 , 推荐系统 , 实时圈人 , 数组 , gin , gist , 索引 , rum , tsvector , tsquery , 万亿 , user , tag , 淘宝背景我们仅用了PostgreSQL的两个小特性,却解决了业务困扰已久的大问题。推荐系统是广告营销平台的奶牛,其核心是精准、实时、..._实时圈人

软件测试风险追踪表_软件测试风险管理表格-程序员宅基地

文章浏览阅读430次。软件测试风险追踪表风险追踪表 项目名称: 填制人: 编号 风险描述 影响 风险等级 发生的可能性 应对策略 状态 责任人 备注 ..._软件测试风险管理表格

AAC ADTS封装实现-程序员宅基地

文章浏览阅读1.2k次。一、AAC音频格式种类有哪些AAC音频格式是一种由MPEG-4标准定义的有损音频压缩格式。AAC包含两种格式 ADIF(Audio Data Interchange Format音频数据交换格式)和ADTS(Audio Data transport Stream音频数据传输流)。ADIF特点:可以确定的找到音视频数据的开始,不需要进行在音视频数据流中间开始的解码,它的解码必须在明确的定义开始。应用场景:常用在磁盘文件中。ADTS特点:具有同步字的比特流,解码可以在这个流中任何位置开始。类似于mp_aac adts

Unity基础概念_unity基本概念-程序员宅基地

文章浏览阅读213次。像要使用Resouce类,必须创建一个 Resouce 文件夹,然后把需要的资源放进去,才可以在代码中设置路径进行访问_unity基本概念

在gitlab中指定自定义 CI/CD 配置文件_gitlab配置cicd-程序员宅基地

文章浏览阅读2.4k次。指定自定义 CI/CD 配置文件,顾名思义就是在项目中指定文件来代替默认的.gitlab-ci.yml文件的方式来运行流水线。以往我们在使用流水线的时候,都是默认将.gitlab-ci.yml文件存在在项目的跟路径下,但是我们也可以指定备用文件名路径,或者不想在每个项目中来维护这个yml文件,那么通过自定义 CI/CD 配置文件便可以实现。_gitlab配置cicd

mysql出现#1063 - Incorrect column specifier for column 'id'的解决方法_sql 错误 [1063] [42000]: incorrect column specifier -程序员宅基地

文章浏览阅读1w次。出现这个表示如果设置了自动增长,字段类型应该设置为int整型。_sql 错误 [1063] [42000]: incorrect column specifier for column 'id' incorrec