深入理解网络原理3----TCP核心特性介绍(上)【面试高频考点】
文章目录
- 前言
- TCP协议段格式
- 一、确认应答【保证可靠性传输的机制】
- 二、超时重传【保证可靠性传输的机制】
- 三、连接管理机制【保证可靠性传输的机制】
- 3.1建立连接(TCP三次握手)---经典面试题
- 3.2断开连接(四次挥手)
- 3.3TCP状态转换
- 四、滑动窗口
- 五、流量控制
前言
随着时代的发展,越来越需要计算机之间互相通信,共享软件和数据,即以多个计算机协同⼯作来完成业务,就有了⽹络互连。
TCP协议段格式
一、确认应答【保证可靠性传输的机制】
确认应答,这是保证“可靠性”最核心的机制。
发送方发完数据之后,接收方收到数据就会返回一个应答报文ACK,每⼀个ACK都带有对应的确认序列号, 意思是告诉发送者, 我已经收到了哪些数据; 下⼀次你从哪⾥开始发。发送方看到应答报文,就知道上个数据传输成功了。
如何解决“先发后至”问题?
引入序号和确认序号,区分出数据的顺序,接收方会按照序号把数据重新排序,确保应用程序read到的数据的顺序和发送顺序一致。
二、超时重传【保证可靠性传输的机制】
在网络传输中,丢包是一个普遍情况,无法预测哪个包会丢,也无法预测什么时候丢。
发送方如果一段时间之内,没有收到ACK应答报文(发的消息本身丢包),就会视为丢包,触发重传,通过重传操作,可以大幅度提升数据包到达对面的概率,但是重传也不是立即重传,数据在网络传输过程中,是需要时间的,等到达到超时时间(往往是一个ms甚至s级的数据)之后,再进行重传。
当前传输的数据,如果是数据到了,ACK丢了也会触发超时重传,此时可能导致接收方收到了重复的数据。TCP协议需要能够识别出哪些包是重复的包, 并且把重复的丢弃掉,这时候我们可以利⽤前⾯提到的序列号, 就可以很容易做到去重的效果。超时时间也不是固定数值,会随着重传的次数增加而增加(重传频率越来越低)。
那么, 如果超时的时间如何确定?
• 最理想的情况下, 找到⼀个最⼩的时间, 保证 “确认应答⼀定能在这个时间内返回”.
• 但是这个时间的⻓短, 随着⽹络环境的不同, 是有差异的.
• 如果超时时间设的太⻓, 会影响整体的重传效率;
• 如果超时时间设的太短, 有可能会频繁发送重复的包;
TCP为了保证⽆论在任何环境下都能⽐较⾼性能的通信, 因此会动态计算这个最⼤超时时间.
• Linux中(BSD Unix和Windows也是如此), 超时以500ms为⼀个单位进⾏控制, 每次判定超时重发的
超时时间都是500ms的整数倍.
• 如果重发⼀次之后, 仍然得不到应答, 等待 2500ms 后再进⾏重传.
• 如果仍然得不到应答, 等待 4500ms 进⾏重传. 依次类推, 以指数形式递增.
• 累计到⼀定的重传次数, TCP认为⽹络或者对端主机出现异常, 强制关闭连接.
三、连接管理机制【保证可靠性传输的机制】
3.1建立连接(TCP三次握手)—经典面试题
客户端执行,socket=new Socket(serverlp,serverPort);这个操作就是在建立连接;上述只是调用socket api,真正建立连接的过程,是在操作系统内核完成的。
内核是怎样完成上述“建立连接”过程的呢?
客户端是主动的一方,第一次交互,一定是客户端主动发起的。
所谓的syn是一个特殊的TCP数据报:
①它没有载荷,不会携带应用层数据,但是也会带有IP报头、以太网数据帧帧头、TCP报头…;
②六个标志位中第五位(SYN)为1。
服务器收到syn之后,会返回ack(确认应答),语义就是收到。接下来服务器还会返回syn,这个syn的语义就是愿意和你建立连接。最后客户端也要返回ack。
下面这张图非常重要=
所谓建立连接的过程,本质上就是通信双方各自给对方发起一个syn,各自给对方回应一个ack。就是为了让通信双方保存对方的信息。
建⽴连接(TCP三次握手)的意义:
1. 投⽯问路, 确认当前通信链路是否畅通,以及检验每个主机的发送能力和接收能力是否正常。eg.玩家A和玩家B尝试连麦打游戏
2. 协商参数, 通信双⽅共同确认⼀些通信中的必备参数数值,使客户端和服务器使用相同的参数进行消息传输。
Q:TCP为啥是三次握手?四次可不可以?两次可不可以?(经典面试题)
A:三次握手是为了确保双方建立起可靠的连接,并且在通信过程中能够进行可靠的数据传输。第一次握手是客户端向服务器发送请求连接的报文段,第二次握手是服务器接收到请求后确认连接,并向客户端发送确认报文段,第三次握手是客户端接收到确认后再次向服务器发送确认报文段,双方完成连接。
四次握手理论上也可以实现可靠的连接,但是通常情况下三次握手已经足够满足连接的可靠性要求,所以四次握手会增加连接的建立时间和网络负担,没有必要。
两次握手并不安全,因为服务器这边无法确认自身的发送能力对端的接收能力是否正确,此时就缺少了“可靠传输”前提,因此客户端必须再来一次握手普,把上述信息同步给服务器,否则无法确保连接双方都已经准备就绪,容易造成数据的丢失或混乱,所以通常不采用两次握手方式。
因此,三次握手是为了在保证连接可靠性的前提下,最大限度地减少连接建立的时间和网络负担,是一种合理且有效的方式。
3.2断开连接(四次挥手)
断开连接的本质目的,就是为了把对端的信息,从数据结构中给删除掉/释放掉。
四次挥手,不一定得是客户端先发fin,服务器也可能先发fin,关键看代码如何写,调用socket.close()就会触发FIN(FIN也是内核负责完成),如果进程直接结束,也会触发FIN,关闭socket文件,结束进程,也会关闭文件。
Q:TCP三次握手与四次挥手的相似之处和不同之处?
A:
3.3TCP状态转换
TCP客户端和服务器都要有一定的数据结构来保存这个连接的信息,在这个数据结构中其中就有一种属性叫做“状态”,操作系统内核根据状态的不同,决定了当前要做什么。
几个重要状态如下:
TIME_WAIT
想⼀想, 为什么是TIME_WAIT的时间是2MSL?
• MSL是TCP报⽂的最⼤⽣存时间,因此TIME_WAIT持续存在2MSL的话
• 就能保证在两个传输⽅向上的尚未被接收或迟到的报⽂段都已经消失(否则服务器⽴刻重启, 可能会收到来⾃上⼀个进程的迟到的数据, 但是这种数据很可能是错误的);
• 同时也是在理论上保证最后⼀个报⽂可靠到达(假设最后⼀个ACK丢失,那么服务器会再重发⼀个 FIN. 这时虽然客⼾端的进程不在了, 但是TCP连接还在, 仍然可以重发LAST_ACK);
CLOSE_WAIT
⼀般⽽⾔,对于服务器上出现⼤量的 CLOSE_WAIT 状态, 原因就是服务器没有正确的关闭 socket, 导致 四次挥⼿没有正确完成.这是⼀个 BUG. 只需要加上对应的 close 即可解决问题.
四、滑动窗口
这是TCP中非常有特点的机制。能提高传输效率,快速重传,处理丢包的情况。
确认应答,超时重传,连接管理==>确保可靠传输,但是也付出了代价——传输效率,单位时间内,能传输的数据量变少了。
因此,我们希望保证可靠传输的前提下,能够让效率尽量高一些,让消耗的时间成本尽可能少一些。滑动窗口的提出就解决了上述问题。注意这里的提高效率其实是降低损失,而不是增加速度。
⼀发⼀收的⽅式性能较低, 那么我们⼀次发送多条数据, 就可以⼤⼤的提⾼性能(其实是将多个段的等待时间重叠在⼀起了)。
• 窗⼝大小指的是⽆需等待确认应答⽽可以继续发送数据的最⼤值. 上图的窗⼝⼤⼩就是4000个字节 (四个段).
• 发送前四个段的时候,不需要等待任何ACK, 直接发送; • 收到第⼀个ACK后, 滑动窗⼝向后移动, 继续发送第五个段的数据; 依次类推;
•操作系统内核为了维护这个滑动窗⼝, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只 有确认应答过的数据, 才能从缓冲区删掉;
•窗⼝越⼤, 则⽹络的吞吐率就越⾼;
滑动窗口,要保证可靠性是前提,那么如果出现了丢包, 如何进⾏重传? 这⾥分两种情况讨论。
情况⼀: 数据包已经抵达, ACK被丢了。
这种情况下,无需进行任何处理,除非是所有的 ACK 都丢失了(网络出现重大故障),否则只是出现一部分 ACK 的丢失,对于可靠性传输没有任何影响,也不需要进行重传。情况⼆: 数据包就直接丢了。
这里的重传做到了“针对性”重传,哪个丢了就重传哪个,已经收到的数据,是不必重复发送的,整体的效率没有额外损失,这种机制被称为 “⾼速重发控制”(也叫 “快重传”)
确认应答,超时重传;滑动窗口,快速重传;这两者并不冲突,而且是同时存在的,滑动窗口中也有确认应答。只不过等待策略稍作调整,转成批量的,批量的前提是短时间发送了很多数据,如果通信双方大规模传输数据,用滑动窗口,按照快速重传保证可靠性,此时判定丢包的标准就是看连续有多个ack索要一个数据。如果通信双方传输数据规模较小,用超时重传。仍按照超时重传保证可靠性,此时判定丢包的标准就是达到超时时间还没有ack到达。
五、流量控制
接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送, 就会造成丢包, 继⽽引起丢包重传等等⼀系列连锁反应。因此TCP⽀持根据接收端的处理能⼒, 来决定发送端的发送速度.。这个机制就叫做流量控制(FlowControl)。
• 接收端将⾃⼰可以接收的缓冲区大小放⼊ TCP ⾸部中的 “窗⼝大小” 字段, 通过ACK端通知发送端;
• 窗⼝大小字段越⼤, 说明⽹络的吞吐量越⾼;
• 接收端⼀旦发现⾃⼰的缓冲区快满了, 就会将窗⼝大小设置成⼀个更小的值通知给发送端;
• 发送端接受到这个窗⼝之后, 就会减慢自己的发送速度;
• 如果接收端缓冲区满了, 就会将窗⼝置为0; 这时发送⽅不再发送数据, 但是需要定期发送⼀个窗⼝探测数据段, 使接收端把窗⼝大小告诉发送端。
接收端如何把窗⼝大小告诉发送端呢?
TCP⾸部中, 有⼀个16位窗⼝字段, 就是存放了窗⼝大小信息;通过这个字段来给发送方反馈发送速度,这个字段要在ack报文中才有意义。通过这个大小反馈给发送方接下来要发送的窗口设置成多少合适。接收方会按照自己接收缓冲区剩余空间的大小,作为ack中的窗口大小的数值,下一步发送方就会根据这个数值来调整自己的窗口大小。
那么问题来了, 16位数字最⼤表⽰65535, 那么TCP窗⼝最⼤就是65535字节(64KB)么?
实际上, TCP⾸部40字节选项中还包含了⼀个窗⼝扩⼤因⼦M, 实际窗⼝大小是窗⼝字段的值左移 M 位。
最后,码字不易,如果觉得对你有帮助的话请点个赞吧,关注我,一起学习,一起进步!
相关文章:

深入理解网络原理3----TCP核心特性介绍(上)【面试高频考点】
文章目录 前言TCP协议段格式一、确认应答【保证可靠性传输的机制】二、超时重传【保证可靠性传输的机制】三、连接管理机制【保证可靠性传输的机制】3.1建立连接(TCP三次握手)---经典面试题3.2断开连接(四次挥手)3.3TCP状态转换 四…...
Java并发编程之锁的艺术:面试与实战指南(三)
Java并发编程之锁的艺术:面试与实战指南(三) 文章目录 Java并发编程之锁的艺术:面试与实战指南(三)前言十七、Java中线程和进程的区别是什么?十八、什么是Java内存模型(JMMÿ…...

Final Draft 12 for Mac:高效专业剧本创作软件
对于剧本创作者来说,一款高效、专业的写作工具是不可或缺的。Final Draft 12 for Mac就是这样一款完美的选择。这款专为Mac用户设计的剧本创作软件,凭借其卓越的性能和丰富的功能,让您的剧本创作更加得心应手。 Final Draft 12支持多种剧本格…...
php字符串变量和常见的字符串函数
在 PHP 中,字符串变量用于存储文本数据。你可以使用单引号()、双引号(")或定界符(heredoc 或 nowdoc)来定义字符串。下面是一些关于 PHP 字符串变量的重要点和示例: 1. 单引号…...

PPT基础
5种ppt仅可读形式 Ⅰ 开始选项卡 1.【幻灯片】组中:新建幻灯片,从大纲中导入幻灯片;修改幻灯片的版式;节(新增节,重命名节)。 2.【字体】组中:设置字体,字体大小&…...
初识JDBC
1、JDBC是什么? Java DataBase Connectivity(Java语言连接数据库) 2、JDBC的本质是什么? JDBC是SUN公司制定的一套接口(interface) java.sql.*;(这个包下有很多接口) 接口都有调用者和实现者。 面向接口调用、面向接口写实现类,这都属于…...
React 学习-5
React 条件渲染: 与js中的写法一致 注意:在 JavaScript 中,true && expression 总是返回 expression,而 false && expression 总是返回 false。 因此,如果条件是 true,&& 右侧的元素就会被渲…...

深入浅出TCP 与 UDP
🔥 个人主页:空白诗 文章目录 🔥 引言🌐 基础认知概览💻 TCP - 稳健的信使 🛡️🎭 UDP - 敏捷的使者 🏃♂️ 🧑💻 实战演练:代码示例TCP 服务…...

Leetcode—387. 字符串中的第一个唯一字符【简单】
2024每日刷题(127) Leetcode—387. 字符串中的第一个唯一字符 实现代码 class Solution { public:int firstUniqChar(string s) {int count[26] {0};for(char c: s) {count[c - a];}for(int i 0; i < s.length(); i) {if(count[s[i] - a] 1) {re…...

Blazor入门-调用js+例子
参考: Blazor入门笔记(3)-C#与JS交互 - 半野 - 博客园 https://www.cnblogs.com/zxyao/p/12638233.html 本地环境:win10, visual studio 2022 community 其他例子写了再更新! 调用js函数并传递参数 首先要加上injec…...

暴力数据结构之栈与队列(队列详解)
1.队列的定义 队列是一种特殊的线性表,它遵循先进先出(FIFO)的原则。在队列中,只允许在表的一端进行插入操作(队尾),而在另一端进行删除操作(队头)。这种数据结构确保了最…...
仿照JDK源码写一个ArrayList实现
仿照JDK编写一个简化的ArrayList实现是一个很好的学习Java集合框架内部工作原理的方式。以下是一个简化版的ArrayList实现,它包含了基本的添加、获取、删除和大小检查功能。 public class MyArrayList<E> {private static final int DEFAULT_CAPACITY = 10;private Obj…...
[链表专题]力扣21, 234
1. 力扣21 题 : 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1:输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4] 示例 2:输入:l1 [], l2 [] 输出&…...

智慧便民小程序源码系统 求职招聘+房产出租+相亲交友 带完整的安装代码包以及系统搭建教程
在数字化、智能化的今天,我们的生活节奏越来越快,对于各种服务的需求也越发多元化和个性化。为了满足广大市民对于便捷、高效、全面的服务需求,罗峰给大家分享一款智慧便民小程序源码系统,集求职招聘、房产出租、相亲交友三大功能…...
苹果免签封装的优势和安全风险
哈喽,大家好呀,淼淼又来和大家见面啦,许多小伙伴应该都知道,App Store一直是iOS应用的主要分发渠道,苹果生态系统的监管是十分严格的,以此确保了应用质量与用户的安全。而苹果免签封装则是有一种不需要通过…...
hook抓包trace定位实战
title: SO逆向之大众点评cx date: 2022-02-07 19:27:28 tags: SOfrida categories: 安卓逆向 toc_number: true抓包10.37.13 打开首页一篇文章,APP默认TCP连接,通过降级采用HTTP连接 jadx反编译代码中 public int g() {Object[] objArr = new Object[0];ChangeQuickRedire…...

SMB 协议详解之-TreeID原理和SMB数据包分析技巧
在前面分析SMB协议数据包的过程中,这里,可以看到在SMB协议中存在很多的ID,即Unique Identifiers。那么这些ID表示什么含义?在实际分析数据包的过程中如何根据这些ID进行过滤分析?本文将介绍SMB/SMB2中的tree id ,并介绍如何通过tree id 快速的分析SMB数据包中各种命令交互…...
博士阶段应该搞什么:-人才引进要求
目录 专利,高水平论文(一作),技能证书,职称,高端竞赛,科研成果奖 济宁学院...

超全MySQL锁机制介绍
前言 MySQL作为关系型数据库管理系统中的佼佼者,为了保证数据的一致性和完整性,在并发控制方面采用了锁机制。锁机制是数据库管理系统用于控制对共享资源的访问,避免多个事务同时修改同一数据造成的数据不一致问题。了解MySQL的锁机制对于数…...
【CV】计算机视觉中的特征追踪与背景处理
计算机视觉领域中的重要任务之一是视频特征追踪,它可以用于目标跟踪、运动分析、行为识别等应用。然而,在实际应用中,经常会遇到需要仅处理视频中特定特征物体而忽略背景的情况,这就需要进行背景处理。本文将介绍如何使用Python和…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...