网络通信协议篇(二)

2020 年 3 月 22 日

网络通信协议篇(二)

连接概述


顺着第一篇的思路下来,到最后我们已经可以依靠分层达到两台主机之间的自由通信,那么问题来了,假设现在有主机 A(客户端)及主机 B(服务端),其中主机 A 需要访问主机 B 的资源,需要哪几个必要条件呢?经过上篇文章可知至少需要四个条件:


  • 主机A需要具有一个ip地址

  • 主机B需要具有一个ip地址

  • 主机A需要具有一个客户端端口号

  • 主机B需要具有一个服务端端口号



具备上述四个条件后 A 获取 B 的信息是有要求的,根本上的要求是数据信道可靠,就是平时所说的可靠连接,那么如何保证连接的可靠性呢,TCP 协议就是靠确认应答机制、超时重传机制等保证连接可靠性的,接下来就通过 TCP 协议的三次握手及四次(三次)挥手来分析一下 A 与 B 建立连接、关闭连接的技术细节是如何落地实现的。


三次握手


第一次:首先客户端 A 会向服务端 B 发送一个数据同步请求,可以称为建立连接请求 syn,同时客户端 A 的 cpu 内核会为这个 syn 请求生成一个随机的序列号 seq 发送给服务端。此处整体称为第一次握手,注意此处为随机序列号。


第二次:服务端 B 接到客户端 A 发送的 syn 请求后,会回复一个[syn+ack]的响应,其中 syn 仍表达数据同步的意思,这个应答 seq 值由服务端 B 的 cpu 随机生成,ack 的值为第一次握手 seq 的值+1,ack 表示两层含义:


  • 服务端B已经收到了客户端A发过来的数据同步请求

  • 希望客户端接下来的应答消息的seq的值以ack回复的值开始传输。


这个称为第二次握手。


第三次:客户端 A 接收到服务端 B 的[syn+ack]应答消息会给 B 回复一个 ack 应答,ack 消息中 seq 值为第二次握手 ack 的值,而 ack 则为第二次握手的请求的 seq 值+1。



三次握手通信释义图如上所示,接下来我们来通过抓包的形式来看一下实际报文,印证三次握手的报文通信。


笔者通过 wireshark(抓包工具)抓取数据包,采用打开一个浏览器网页的场景模拟对服务器 B 的请求。


第一次握手抓包图如下:



第二次握手抓包释义图如下:



第三次握手抓包释义图如下:



通过三次握手的抓包可以很清晰的展示三次交互流程,可能有人会有连带的疑问,为什么一定是三次,而不是别的次数,这里三次其实是最优的次数,而不是一定的次数,比如如果两次的话 A、B 两方将会有一方无法做出信息是否送达的确认,而超过三次则造成了浪费,因为三次交互中 A、B 都已经对两方应答一次了。接下来来看一下四次挥手的交互流程。


四次挥手


理解三次握手及流程后,四次挥手其实本质和三次握手的确认流程基本上是一样的,下面我们简单梳理一下挥手标准流程。


第一次:当 A 确认当前连接数据已经全部发送完成以后,会发起关闭连接请求,此时 A 不再发送业务报文,发送的请求标志为 FIN ,seq 为 x,此处整体为第一次挥手。


第二次:B 收到 A 发出的关闭连接的请求之后,会给 A 一个确认响应,告诉 A 我收到你关闭连接的请求了,但是我有可能还有没发完的数据需要继续给你发送,响应的标志为 ack,seq 为 Y,ack 为 x+1,此处整体为第二次挥手。


第三次:当 B 把数据传输完之后会发送释放连接响应,此处标志 B 释放连接,不会再发送业务报文,此时请求的标志为 FIN+ack,seq 的值为 y,ack 的值为 x+1,此处整体为第三次挥手。


第四次:A 对 B 第三次挥手做最后确认,并释放连接,此时请求标志为 ack,seq 为 x+1,ack 为 y+1。



四次挥手通信释义图如上所示,由于三次握手的每一次都通过抓包工具详细描述了通信详情,此处挥手抓一个整体包截图,由读者自行解析分析即可。


四次挥手抓包整体释义图如下:



可以看到,这里面的挥手包数与咱们分析的标准流程不一样,这里是因为第二次和第三次挥手都是 B 向 A 发起确认响应,区别是第二次只是确认,因为可能还有数据没有传完,要继续传,全部数据传完后 B 才能发出最后指令进行释放连接,但这时如果发第二次挥手的时候就可以确认没有数据需要再同步给 A 了,这时如果按照标准流程,B 会给 A 发送两个相同的数据包,这样就造成了资源浪费,故这块挥手做了优化,可以确认数据的情况下,可以把第二次和第三次挥手合并成一次,所以此处是三次握手。


小结


本文梳理了 TCP 建立连接概述、三次握手、四次挥手的流程,下一篇将会从控制报文协议 ICMP 及常用网络工具命令 ping、traceroute 为切入点分析控制消息的设计及实现机制,小伙伴们如果对本文有疑问可以留言或者加我微信咨询,大家一起进步。


2020 年 3 月 22 日 21:05132

评论

发布
暂无评论
发现更多内容

一个产品最不重要的东西

Neco.W

产品 外包 产品经理

一个前端工程师与死神的较量

陈辰

前端工程 压力 医院 生活质量 工程师

程序员的修行之路-人生是一场修行

牧马人

程序员人生

教你快速升职加薪(毒鸡汤,慎服……)

无箭的丘比特

团队管理 企业文化 个人成长 团队建设

为什么要云原生?

Aaron_涛

架构 云原生

一文搞懂Spring依赖注入

麦叔

3亿办公族合力,第三代SaaS抵达战场

人称T客

用友2019财报:你们看到的是数字,我却看到了office

人称T客

Spring Security 如何将用户数据存入数据库?

江南一点雨

Java spring Spring Cloud Spring Boot spring security

Java开发架构篇:DDD模型领域层决策规则树服务设计

小傅哥

领域驱动设计 DDD 小傅哥 重构

分布式系统选主怎么玩

奈学教育

分布式系统

市场调研分析师走向末法时代

人称T客

SaaS生态比拼,谁会是这场PK中的主角?

人称T客

python实现·十大排序算法之冒泡排序(Bubble Sort)

南风以南

Python 排序算法 冒泡排序

Linux 常用命令

Jayli

Linux

c++代码整洁之道

程序喵大人

c c++ C#

忙于数字化转型,你避坑了吗?

人称T客

永中云转换新升级 文档在线预览增添更多选择

DT极客

Spring Security+Spring Data Jpa 强强联手,安全管理只有更简单!

江南一点雨

Java spring Spring Boot spring security

BPM产业数字观察:中国市场趋向成熟,蛰伏的BPM即将醒来

人称T客

程序员的修行之路-培养工作兴趣

牧马人

程序员人生

kube-prometheus抓取jvm监控指标

天飞

Java JVM Prometheus kubernete

首厚智能:嵌入 SpreadJS 表格组件,搭建实验室信息管理系统(LIMS)

Geek_Willie

SpreadJS 实验室管理系统 Lims

k8s上运行我们的springboot服务之——热点数据

柠檬

redis

游戏夜读 | 写游戏用什么语言?

game1night

金蝶2019财报在此——比头条更精彩

人称T客

极客时间学习心得:用分类和聚焦全面夯实技术认知

Anfernee Hu

学习

用Serverlss部署一个基于深度学习的古诗词生成API

刘宇

自然语言处理 学习 Serverless

5天掌握以太坊 dApp 开发

陈东泽 EuryChen

比特币 区块链 智能合约 以太坊 dapp

《3个月9门课,谈下我的极客时间学习活动的心得》

王伟鹏

汇总一下Intellij IDEA常用的牛逼插件

公众号:V5codings

网络通信协议篇(二)-InfoQ