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

TCP三次握手四次挥手

一、三次握手

1.概念:

三次握手是指在建立一个TCP连接时,客户端和服务端一共会发送三个报文段。

Seq   序列号   保障传输过程可靠。
ACK   (确认消息)
SYN   (在建立TCP连接的时候使用)
FIN    (在关闭TCP连接的时候使用)

初始时客户端和服务器都处于CLOSED状态,当服务器应用程序创建一个监听套接字时,服务器处于LISTEN状态。

原理一

第一次握手:客户端向服务端发送一个SYN报文段,会指明自己的初始化序号seq=x,此时客户端处于SYN_SENT状态

第二次握手:服务端收到SYN报文段后,会以自己的SYN,ACK报文进行应答,报文首部有三个重要信息,首先SYN被至为1;其次,确认号字段ack=x+1;最后服务器选择自己的初始序号seq=y;(通俗说法:我收到了你发起建立连接的请求,该请求报文的初始序号为x(确认号ack=x+1就表明我收到了初始序号seq=x的报文)我同意建立连接,我的初始号为y)此时服务端处于SYN_RCVD状态

第三次握手: 客户端收到服务端的SYN-ACK报文后,会发送一个ACK报文,该报文段中的序号seq=x+1;确认号为ack=y+1;表明我已经收到你的确认。此时客户端处于ESTABLISHED状态;当服务端收到ACK后;也处于ESTABLISHED状态。

原理二

1)发送端首先发送一个带有SYN(synchronize)标志地数据包给接收方。
2)接收方接收后,回传一个带有SYN/ACK标志的数据包传递确认信息,表示我收到了。
3)最后,发送方再回传一个带有ACK标志的数据包,代表我知道了,表示’握手‘结束。

第一次握手和第二次握手都只是消耗掉一个序号,但不能携带数据;第三次握手可以携带数据

通俗的说法:   

    
1)Client:嘿,李四,是我,听到了吗?
2)Server:我听到了,你能听到我的吗?
3)Client:好的,我们互相都能听到对方的话,我们的通信可以开始了。

2.三次握手的作用:

第一次握手:客户端给服务器发送一个报文,告知服务器:“我客户端想和你建立连接”。

服务器收到第一段报文后得出结论:客户端发送功能正常,服务器接收功能正常

第二次握手:服务器收到报文后给客户端回复一个报文,告知客户端:“我服务器收到了你的请求,同意和你建立连接”。

客户端收到第二段报文后得出结论:客户端发送和接收功能都正常,服务器的发送接收功能也都正常。(但此时服务器不能确认客户端的接收功能和自己的发送功能是否正常)

第三次握手:客户端收到第二段报文后给服务器回复一个报文,告知服务器:“我客户端收到了你的回复,知道你同意连接,那我们开始连接吧!”

服务器收到第三段报文后得出结论:客户端的接收功能和服务器的发送功能也都正常。

所以当服务器收到第三个报文后,两边就建立起了TCP连接。

3. 两次握手为什么不行?

    只有前两次握手的话,服务器就不能确认自己回复的报文段是否被客户端接收到,也就不知道自己的发送功能和客户端的接收功能是否正常。

二、四次挥手

1、基本概念

概念:四次挥手也就是客户端与服务器断开连接时,需要一共发送四个报文段来完成断开TCP连接。

  初始时,客户端与服务器都处于ESTABLISHED状态,假如客户端发起断开连接的请求(服务器也可以发起),四次挥手过程如下:

原理一:

1.第一次挥手客户端发送一个FIN报文段,报文段中指定序号seq=u。此时客户端处于FIN_WAIT_1状态。

2.第二次挥手服务器收到FIN报文后,立即发送一个ACK报文段,确认号为ack=u+1,序号设为seq=v。表明已经收到了客户端的报文。此时服务器处于CLOSE_WAIT状态。

在第二次挥手和第三次挥手之间的时间段内,由于只是半关闭的状态,数据还是可以从服务器传送到客户端的。

3.第三次挥手:如果数据传送完毕,服务器也想断开连接,那么就发送一个FIN报文,并重新指定一个序号seq=w,确认号还是ack=u+1,表明可以断开连接。

4.第四次挥手客户端收到报文后,一样发出一个ACK报文段做出应答,上一次客户端发送的报文段序号为u,那么这次序号就是seq=u+1,确认号为ack=w+1。此时客户端处于TIME_WAIT状态,需要经过一段时间确保服务器收到自己的应答报文后,才会进入CLOSED状态。

 原理二:

1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送。
 2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1
 3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送.
 4)第四次挥手:Client收到FIN后,接着发送一个ACK给Server,确认序号为收到序号+1.

通俗的说法


1)Client:我所有东西都说完了
2)Server:我已经全部听到了,但是等等我,我还没说完
3)Server:好了,我已经说完了
4)Client:好的,那我们的通信结束

2.中间两个步骤可以合并吗?

不行,因为ACK和FIN的触发时机是不一样的。我们要搞清楚一件事:服务器在收到FIN报文后可以立即发送ACK报文,表明我服务器收到了你的报文;但是服务器想发送FIN报文就需要等到处理完接收缓冲区的数据后才可以。所以挥手需要四次。

http://www.lryc.cn/news/174303.html

相关文章:

  • C语言基础-结构体
  • Codeforces Round 848 (Div. 2)C
  • 数据分发服务DDS
  • Linux 文件 目录管理 链接
  • R统计绘图-线性混合效应模型详解(理论、模型构建、检验、选择、方差分解及结果可视化)
  • 钾和钠含量
  • Linux离线安装elasticsearch|header|kibna插件最详细
  • 网络协议学习地图分享
  • nlohmann/json——NLOHMANN_JSON_SERIALIZE_ENUM
  • 类和对象:运算符重载
  • Vue中使用VueAMap
  • Vue中的路由介绍以及Node.js的使用
  • 将本地项目上传至Github详解
  • Vivado下PLL实验
  • 简单理解推挽输出和开漏输出
  • C++之va_start、vasprintf、va_end应用总结(二百二十六)
  • OpenCV自学笔记十一:形态学操作(一)
  • 封装全局异常处理
  • python的requests响应请求,结果乱码,即使设置了response.encoding也没有用的解决方法
  • PyCharm 手动下载插件
  • Gnomon绑定基础(约束 IK 节点)
  • STL常用遍历,查找,算法
  • BCC源码内容概览(1)
  • mysql限制用户登录失败次数,限制时间
  • 从利用Arthas排查线上Fastjson问题到Java动态字节码技术(下)
  • Ubuntu中安装Anaconda 如何将 路径导入为全局变量
  • 【QT】Qt的随身笔记(持续更新...)
  • 【LeetCode-简单题】589. N 叉树的前序遍历
  • Linphone3.5.2 ARM RV1109音视频对讲开发记录
  • Unity用相机实现的镜子效果