网络协议和Netty(4):大白话说三次握手及用一个数据库连接解释三次握手

本文主要是介绍网络协议和Netty(4):大白话说三次握手及用一个数据库连接解释三次握手,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

想起了第一次听说“三次握手”概念的时候。那时候刚到北京,朋友傲娇的跟我讲,我花了两天我终于搞懂了三次握手。当时对网络一无所知的我,还以为是啥新的礼仪方式,心中感叹,帝都人民的热情,握手还要三次。说到半途才搞清楚,原来是TCP创建连接的礼仪。后面空闲的时候,经常从网上找些找些资料,接触“三次握手”。用网友经典的打电话例子,浅浅的理解。时间推移,由浅入深。大概所有人都跟我一开始有同样以下的这个问题:

提问:

为啥TCP建立连接需要进行三次握手?

三次握手

回答问题前,我还是想老生常谈的自己讲解下什么是三次握手。

何为三次握手?

比起语言叙述,有时候图会先的更具体和简单易懂:

 

 

图文讲解

讲解SYN和ACK:

客户端和服务端进行三次握手时除了必要的传输数据,还会有标志位信息。三次握手时,SYN和ACK就是标志位。标志位的作用是,让服务端/客户端根据不同的标志位来确定当前的数据进行对应处理。

比如当服务端发现标志位是SYN=1,就会知道当前的数据是进行第一次握手的请求,然后就会按照第一次握手的规则来处理信息。同样第二次握手时客户端根据SYN=1,ACK=1标志位就会确定是来自服务端的第二次握手的应答请求,然后进行相应的处理。

第一次握手:

由客户端发起,当客户端发起SYN请求后,将客户端状置为SYN_SENT状态,等待服务端确认。此时请求信息中标志位SYN=1,序列Seq=n。

第二次握手:

服务端接收到SYN请求,将Seq在原来值n得基础上加1,赋值Ack=n+1。并且服务端再生成一个序列号m,赋值Aeq=m。服务端应答请求,标志位SYN=1、ACK=1,序列信息Seq=m、Ack=n+1,同时将服务端状态置为SYN_RCVD,等待客户端确认。

第三次握手:

客户端接收到消息,根据标志位SYN=1、ACK=1解析数据,确认Ack=n+1,然后序列赋值Ack=m+1。客户端向服务端发起ACK=1请求。客户端接收到请求,根据标志位ACK=1,校验序列Ack=m+1。校验无误后,将客户端和服务端状态置为ESTABLISHED,建立连接,就可以进行正常的通讯了。

总结:

我们发现所谓三次握手,不过就是客户端和服务端,通过发送三次数据包,来确认连接建立。

我们又知道,TCP的是一个双工连接,即是一个双向连接,就是服务端和客户端都有数据的发送和接收能力。

这就很好的解答了,为何TCP建立连接需要三次握手

客户端和服务端都必须确认数据是否准确的发送和接收,而在三次握手中序列Seq和Ack的发送和接收,就代表着数据的准确发送和接收。

假如进行两次握手,只有客户端校验了自己生成的序列号,确认了自己的发送和接收能力,很明显是不够的。那为啥不能是四次?我只能说,任何事情三次能解决的事,没必要四次,更何况是作为程序员去解决问题。

用一个数据库连接来验证三次握手:

准备:wireshark(抓包工具),navicat(数据库可视化工具),mysql

说明:mysql的连接是一个TCP连接

1.打开wireshark

2.打开navicat

此时并没有创建连接。

3.wireshark编辑捕获器,监听3306端口(mysql连接端口)

4.点击开始

由于3306端口暂无通信所以为空

5.点击navicat其中一个数据库连接

6.我们发现3306端口有数据包

我们先简单看下前三No1、No2、No3

注意标志位和Seq是不是有些似曾相识,和我们上面上述的三次握手是不是有些相似?

详细看下:

第一个包No1:

下方红色框框SYN=1 ,说明这是第一次握手,上方黄色框为客户端生成的序列号Seq=0。

第二个包No2:

 下方红色框框SYN=1 和ACK=1,说明这是第二次握手,上方黄色框为服务端生成序列号Seq=0和应答序列号Ack=1(即Ack=客户端值为0的Seq+1)。

第三个包No3:

下方红色框框ACK=1,说明这是第三次握手,上方黄色框为客户端应答序列号Ack=1(即Ack=服务端生成的seq+1)。

总计:三次握手双方的序列号都校验无误,故三次握手成功,建立连接,所以有了下方的No4,5,6等等的数据传输

 

 

 

 

这篇关于网络协议和Netty(4):大白话说三次握手及用一个数据库连接解释三次握手的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/904590

相关文章

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

使用shardingsphere实现mysql数据库分片方式

《使用shardingsphere实现mysql数据库分片方式》本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置... 目录一、ShardingSphere 简介1.1 对比1.2 核心概念1.3 Sharding-Sp

Mac电脑如何通过 IntelliJ IDEA 远程连接 MySQL

《Mac电脑如何通过IntelliJIDEA远程连接MySQL》本文详解Mac通过IntelliJIDEA远程连接MySQL的步骤,本文通过图文并茂的形式给大家介绍的非常详细,感兴趣的朋友跟... 目录MAC电脑通过 IntelliJ IDEA 远程连接 mysql 的详细教程一、前缀条件确认二、打开 ID

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

MySQL 数据库表与查询操作实战案例

《MySQL数据库表与查询操作实战案例》本文将通过实际案例,详细介绍MySQL中数据库表的设计、数据插入以及常用的查询操作,帮助初学者快速上手,感兴趣的朋友跟随小编一起看看吧... 目录mysql 数据库表操作与查询实战案例项目一:产品相关数据库设计与创建一、数据库及表结构设计二、数据库与表的创建项目二:员

python连接sqlite3简单用法完整例子

《python连接sqlite3简单用法完整例子》SQLite3是一个内置的Python模块,可以通过Python的标准库轻松地使用,无需进行额外安装和配置,:本文主要介绍python连接sqli... 目录1. 连接到数据库2. 创建游标对象3. 创建表4. 插入数据5. 查询数据6. 更新数据7. 删除