JavaEE 网络原理——TCP的工作机制(中篇 三次握手和四次挥手)

文章目录

  • 一、TCP 内部工作机制——连接管理
    • 1. 连接(三次握手)
      • (1).有连接和确认应答之间的关系
      • (2). 通过客户端和服务器详细描述三次握手
    • 2. 断开连接(四次挥手)
      • (1)讨论“四次握手”中间步骤的合并问题。
      • (2) 根据简单的 TCP 代码解释断开连接
      • (3) 四次挥手中的两个重要的 TCP 状态
  • 二、连接管理总结

一、TCP 内部工作机制——连接管理

在上一篇文章中,本人描述了保证 TCP 的可靠性的两个关键点:确认应答&超时重传

在这篇文章中所描述的 连接管理 ,对应的就是 TCP 的核心特点——可靠传输。

1. 连接(三次握手)

所谓 “连接” ,就是建立连接,通信双方各自记录对方的信息,彼此之间要有相互认同。

  • TCP 建立连接的最初描述
    TCP 的建立连接,还有一个名字叫做 三次握手
    在这里插入图片描述
    如上图所示,所谓的 三次握手 ,本质上是 “四次” 交互。
    通信双方,各自需要向对方发起一个 “建立连接” 的请求。同时,在各自向对方回应一个 ack 。所以这里一共有四次信息交互。

  • TCP 建立连接的正确形式描述
    上面的 “四次” 交互,是否可以将中间的两次信息交互合并成一个一次交互。从而构成“三次握手”,不合并是否可以? 如图: 在这里插入图片描述 答案是:必须合并! 我们要知道的是,这里的每一步都有着一个特点 “封装分用”。分装分用两次一定分装分用一次,成本更高。

  • TCP 建立连接是使用 “两次握手” 情况的讨论
    所谓 “两次握手” 图示如下:
    在这里插入图片描述
    此时,缺少了一次握手,我们就需要用不同的方式来思考这个问题。
    要讨论这个问题,我们要将视角分为两部分。

1.对于情境中的 “我”。 我明确的点了一份炒面。 我得知了我需要等一会。
2.对于情境中的 “饭店老板”。 得知了我需要一份炒面。
不知道我是否愿意等待。
所以,在上面的两个情况的分析中,从 “饭店老板” 的视角中,“我” 可能就不愿意等待。

通过上面的问题的讨论和分析,我们还可以发现,三次握手除了建立连接之外。还有一个重要的作用——验证双方各自的信息发送和接受功能是否正常!

(1).有连接和确认应答之间的关系

对于这个问题,本人在这里直接说明。有没有连接,和是否确认应答,没有任何关系。

所谓有连接,有下面三点:
1.需要将连接先建立好,才能进行通信。
2.如果断开连接,此时就无法继续通信
3.连接建立过程中,通信双方都要各自保存好对方的信息。

确认应答,所体现的是 “可靠传输” 与是否有连接不相关。
例如,钉钉发送信息就不需要连接,当出现一个 “已读” 状态时。就表明传输成功了。

这里有一个说法,“TCP 中的三次握手,体现出了 TCP 的有连接”
这里正确的理解应该是,因为 TCP 是有连接的,所以,TCP 需要有能够建立连接 / 断开连接的功能。因而,其中的建立连接流程是 三次握手。
并不是说因三次握手才体现出的有连接。

(2). 通过客户端和服务器详细描述三次握手

在描述之前,我们要先知道客户端和服务器在这里的关系。
客户端是主动的一方。
服务器是被动的一方。

在这里插入图片描述
在这里插入图片描述
在上图中 红色 标注出来的是报文段
绿色 标注出来的是 TCP 的状态

  • 红色标注解释
    ACK: 确认号是否有效。
    SYN: 请求建立连接,称之为同步报文段

  • 绿色标注解释
    在建立连接阶段,主要需要认识两个状态:
    1.LISTEN 服务器状态
    这里表示服务器已经准备就绪,随时可以有客户端来建立连接。
    也就是相当于,手机开机信号良好,可以打电话过来了
    2.ESTABLISHED 客户端和服务器的状态。
    连接建立完成,接下来就可以正常进行通信了。
    相当于电话打过去,对方接通了。

2. 断开连接(四次挥手)

“挥手” 和 “握手” 一样都是形象的叫法。都是客户端和服务器之间的数据交互。

四次挥手 和 三次握手 非常类似。就是双方各自向对方发送一条断开连接的请求,在各自给对方一个回应。
在这里插入图片描述
通过上面的图像,我们一样可以提出一个问题,这里的“四次挥手”和前面我们开始时所讲的“三次握手” 两个的图像有很大的相似之处。

(1)讨论“四次握手”中间步骤的合并问题。

所以问题就是,四次握手这里的 中间两步 是否可以合并

对于合并,这里有一个判断准则:两个数据发送的时机相同才能合并,若时机不同,就无法合并。
阐述三次握手时情况
在这里插入图片描述
三次握手中间两次的合并,就是因为同一时机。具体的来讲,三次握手的这三次交互,是纯内核完成的 (应用层感知不到,也无法干预)
服务器的系统内核收到 syn 之后,就会立刻发送 ack 同时也发送 syn。
阐述四次挥手时情况
在这里插入图片描述

在这里插入图片描述

  • 对红色方框元素解释
    FIN: 通知对方,本端将会关闭,该标识称之为结束报文段

首先我们要明确下面的这一点:FIN 的发起,不是由内核进行控制的,而是由应用程序调用 socket 的 close 方法才会触发 FIN。
在上面的图中,服务器收到来自客户端的 FIN 请求后,会立即返回一个 ACK。但是对应返回的 FIN 就需要服务器执行到对应的 close 方法后才会触发返回的 FIN (两者中间会存在一个时间差)

(2) 根据简单的 TCP 代码解释断开连接

在之前的文章中,我向大家介绍了有关 TCP 的部分相关知识。
详见: JavaEE——网络编程(TCP流编程)
在这里,我将通过之前服务器代码对 “四次挥手” 中,中间的两部分应答操作进行简单解释。

  • 观察服务器读取请求代码
    在这里插入图片描述
    注意上面代码中的 break 关键词。这里的 break 决定着是否要跳出 while 循环来停止服务器。
    注意上面的 hasNext 关键字。这里要进入到下面的 break 就需要通过 hasNext 关键字来判断为 false
    但是这里为什么会成为 false ?是因为流对象读取到了 EOF(文件结束标记)
    为什么会收取到 EOF?这是因为内核收取到了客户端发送过来的 FIN 数据报。

在前面我们提到过,当程序执行到对应的 close 方法时,才会触发 FIN。但是在我们的 客户端 代码中,并没有显式的写 close。但是客户端进程的退出,就会触发 socket.close,也就触发 FIN。

  • 服务器关闭代码
    在这里插入图片描述

如上面的代码所示,在循环执行完毕后,执行到了下面的 close 方法。此时,服务器就会向客户端发起一个 FIN。

整体的观察上述代码,我们发现,当前的循环一结束,就立刻有 close 发起 FIN,此时 ACK 和 FIN 之间的间隔较短。此时很有可能系统将这两个包合成到一块发送

要注意的是,虽然时间间隔较短但是任然是不可以忽略的。所以为了可以更加明显一点,可以在 close 方法之前加上 sleep 方法进行短暂的休眠

(3) 四次挥手中的两个重要的 TCP 状态

在这里插入图片描述

  1. CLOSE_WAIT
    出现在被动发起断开连接的一方。 等待关闭。(等待调用 close 方法关闭 socket)
    建立连接一定是客户端主动发起请求。
    断开连接,可能是客户端主动发起请求,也可能是服务器主动发起。

  2. TIME_WAIT
    出现在主动发起断开连接的一方。
    假设客户端主动断开连接。当客户端进入 TIME_WAIT 状态时,相当于四次挥手已经挥完了。
    此时这里的 TIME_WAIT 要保持当前的 TCP 连接状态不要立即释放

为什么不要连接释放?为什么会以 TIME_WAIT 保留一会连接?
理由就是,此时最后一个 ACK 刚刚发送出去,还没有到达,万一出现 ACK 丢包呢?
TIME_WAIT 在这里会进行等待,如果等待一段时间后,还是没有收到重传的 FIN 呢么此时就会认为,最后一个 ACK 没有丢失,于是就会彻底放弃连接。

  • 对于 三次握手 和 四次挥手 的超时重传
    在 三次握手 和 四次挥手 的过程中,同样是存在超时重传的。
    如果最后一个 ACK 丢包了,在服务器的角度来看,服务器不知道是因为 ACK 丢失,还是自己发送的 FIN 丢失,对此,这样的情况统一视为 FIN 丢了,统一进行重传操作
    大致情况如图:
    在这里插入图片描述
    既然服务器可能会重传 FIN客户端就需要能对这个重传的 FIN 进行 ACK 响应。
    既然服务器可能要重传 FIN ,客户端就需要能够针对这个重传的 FIN 进行 ACK 响应。所以,很明显如果刚才将连接彻底释放,这样的 ACK 就无法进行了。因此使用 TIME_WAIT 状态保留一定的时间,就是为了能够处理最后一个 ACK 丢包情况,能够在收到重传的 FIN 后,进行 ACK 响应。

二、连接管理总结

通过前面的描述,我们已经知道,TCP 作为一个有连接的协议。就需要建立连接和断开连接
建立连接: 就是三次握手
对于三次握手的意义,有下面的三点:
1.双方建立对对方的认同。(保存对方的信息)
2.验证通信双方的发送和接受能力。
3.协商一些关键参数。

断开连接: 就是四次挥手
四次挥手,需要重点来理解当前的挥手是四次,理解 FIN 和 ACK 的传输时机,以及 TIME_WAIT 的意义和作用。

码子不易,您小小的点赞是对我最大的鼓励!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/95442.shtml

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

相关文章

@ConfigurationProperties配置绑定~

ConfigurationProperties注解是Spring Boot中的一个注解,用于将配置文件中的属性值绑定到Java类中的字段上。 ConfigurationProperties注解的作用包括: 实现配置文件属性和Java类字段的映射,简化了读取配置文件的操作。 可以指定配置文件中…

React项目部署 - Nginx配置

写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成…

GB28181学习(六)——实时视音频点播(数据传输部分)

GB28181系列文章: 总述:https://blog.csdn.net/www_dong/article/details/132515446 注册与注销:https://blog.csdn.net/www_dong/article/details/132654525 心跳保活:https://blog.csdn.net/www_dong/article/details/132796…

GPT系列论文解读:GPT-2

GPT系列 GPT(Generative Pre-trained Transformer)是一系列基于Transformer架构的预训练语言模型,由OpenAI开发。以下是GPT系列的主要模型: GPT:GPT-1是于2018年发布的第一个版本,它使用了12个Transformer…

企业微信机器人对接GPT

现在网上大部分微信机器人项目都是基于个人微信实现的,常见的类库都是模拟网页版微信接口。 个人微信作为我们自己日常使用的工具,也用于支付场景,很怕因为违规而被封。这时,可以使用我们的企业微信机器人,利用企业微信…

【数据结构】排序(1) ——插入排序 希尔排序

目录 一. 直接插入排序 基本思想 代码实现 时间和空间复杂度 稳定性 二. 希尔排序 基本思想 代码实现 时间和空间复杂度 稳定性 一. 直接插入排序 基本思想 把待排序的记录按其关键码值的大小依次插入到一个已经排好序的有序序列中,直到所有的记录插入完为止&…

程序三高的方法

程序三高的方法 目录概述需求: 设计思路实现思路分析1.1)高并发 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,c…

全志ARM926 Melis2.0系统的开发指引⑤

全志ARM926 Melis2.0系统的开发指引⑤ 编写目的8. 固件修改工具(ImageModify)使用8.1.界面说明8.2.操作步骤8.2.1. 配置平台8.2.2. 选择固件8.2.3. 选择要替换的文件8.2.4. 替换文件8.2.5. 保存固件 8.3.注意事项8.4.增加固件修改权限设置8.4.1. 概述8.4.2. 操作说明8.4.2.1.打…

竞赛选题 机器视觉目标检测 - opencv 深度学习

文章目录 0 前言2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 0 前言 &#x1f5…

Jetpack生命周期感知组件ViewModel

ViewModel Jetpack ViewModel是Android Jetpack组件库中的一个组件,用于帮助开发者管理UI相关的数据和状态。ViewModel的主要作用是存储和管理与UI相关的数据,以及处理UI的状态变化。 使用ViewModel可以解决以下问题: 避免配置变更&#x…

【JavaScript】相等运算符(== 和 ===)

如果x和y的类型相同,JavaScript会用equals 方法比较这两个值或对象。 没有出现在表格中的情况都会返回 false。(表格中的方法都是内部规定的) 对于 toNumber 方法: 对于 toPrimitive 方法: // 举个例子: c…

用JMeter对HTTP接口进行压测(一)压测脚本的书写、调试思路

文章目录 安装JMeter和Groovy为什么选择Groovy? 压测需求以及思路准备JMeter脚本以及脚本正确性验证使用Test Script Recorder来获取整条业务线上涉及的接口为什么使用Test Script Recorder? 配置Test Script Recorder对接口进行动态化处理处理全局变量以…

W25Q128芯片手册精读

文章目录 前言1. 概述2. 特性3. 封装类型和引脚配置3.1 8焊盘WSON 8x6 mm3.2其他封装 4. 引脚描述4.1 片选4.2 串行数据输入输出4.3 写保护4.4 保持脚4.5 时钟 5. 块图6. 功能描述6.1 SPI功能6.1.1 标准SPI6.1.2 双通道SPI6.1.3 四通道SPI6.1.4 保持功能 6.2 写保护6.2.1 写保护…

SRT服务器SLS

目前互联网上的视频直播有两种,一种是基于RTMP协议的直播,这种直播方式上行推流使用RTMP协议,下行播放使用RTMP,HTTPFLV或者HLS,直播延时一般大于3秒,广泛应用秀场、游戏、赛事和事件直播,满足了…

用go获取IPv4地址,WLAN的IPv4地址,本机公网IP地址详解

文章目录 获取IPv4地址获取WLAN的IPv4地址获取本机公网IP地址 获取IPv4地址 下面的代码会打印出本机所有的IPv4地址。这个方法可能会返回多个IP地址,因为一台机器可能有多个网络接口,每个接口可能有一个或多个IP地址。 package mainimport ("fmt&…

GPX可视化工具 GPX航迹预览工具

背景 当我们收到别人分享的航迹文档,即gpx文档时,如何快速的进行浏览呢?我们可以使用GIS软件来打开gpx文档并显示gpx中所记录的航迹,例如常用的GIS软件有googleEarth, Basecamp, GPXsee, GPX E…

超详细DeepLabv3 介绍与使用指南 – 使用 PyTorch 推理

DeepLab 模型首次在 ICLR 14 中首次亮相,是一系列旨在解决语义分割问题的深度学习架构。经过多年的迭代改进,谷歌研究人员的同一个团队在 17 年底发布了广受欢迎的“DeepLabv3”。当时,DeepLabv3 在 Pascal VOC 2012 测试集上实现了最先进的 (SOTA) 性能,在著名的 Cityscap…

VC6 WIN32,Dialog为主窗口编程

VC6是Microsoft非常经典的开发环境,尤其是Windows API方式开发,自从Quick C for win以来基本保持着同样的风格和API,在它上面做习练很不错。下面是习练完成的界面,它是在自动创建的WIN32 application模板下,增加一个Di…

Linux shell编程学习笔记4:修改命令行提示符格式(内容和颜色)

一、命令行提示符格式内容因shell类型而异 Linux终端命令行提示符内容格式则因shell的类型而异,例如CoreLinux默认的shell是sh,其命令行提示符为黑底白字,内容为: tcbox:/$ 其中,tc为当前用户名,box为主机…

Postman使用实例

Postman使用实例 实体类Emp package com.example.springboot_postman.pojo;import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import javax.persistence.*; import j…