深入理解网络原理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和…...

CAPL如何实现TLS握手认证
CAPL有专门的章节介绍如何实现TLS握手认证的函数: CAPL调用哪些函数实现TLS握手认证,需要了解TLS在整个通信过程的哪个阶段。 首先TCP需要建立连接,这是TLS握手的前提。当TLS握手认证完成后,可以传输数据。 所以TLS握手开始前需要确保TCP建立连接,TCP传输数据前需要确保…...

Linux -- 日志
一 日志的重要性 在之前的编程经历中,如果我们的程序运行出现了问题,都是通过 标准输出 或 标准错误 将 错误信息 直接输出到屏幕上,以此来排除程序中的错误。 这在我们以往所写的程序中使用没啥问题,但如果出错的是一个不断在运行…...

WebRtc 视频通话,语音通话实现方案
先了解一下流程 和 流程图(chatGpt的回答) 实现 (底层代码实现, 可作为demo熟悉) 小demo <template><div><video ref"localVideo" autoplay muted></video> <!-- 本地视频元素,用于显示本地视频 --><video ref"r…...

IndyTcpServer使用详解
1、IndyTCPserver的创建 IdTCPServer1.DefaultPort:= 8000; IdTCPServer1.ListenQueue:= 1024; //同时处理请求队列数限制 IdTCPServer1.MaxConnections:= 1024; //同时连接数量限制,为0不限制连接数 IdTCPServer1.ContextClass:= TNewIdServerContext; //设置为自定义TIdSe…...

pytest + yaml 框架 - 参数化读取文件路径优化
针对小伙伴提出参数化时读取外部文件,在项目根路径运行没问题,但是进入到项目下子文件夹运行用例,就会找不到文件问题做了优化。 关于参数化读取外部文件相关内容参考前面这篇pytest yaml 框架 -25.参数化数据支持读取外部文件txt/csv/json/…...

C++:多态-重写和重载
重写(Override)和重载(Overload)是面向对象编程中常用的两个概念,它们虽然都涉及到方法的定义,但是在实现和使用上有着不同的特点。 重写(Override): 重写是指在子类中重…...

element ui的table多选
使用el-table的selection-change事件来获取选中的值; 例: html代码: <el-button type"primary" click"openTableSet">列表设置</el-button><!-- 列表设置弹框 --> <el-dialog :close-on-click-mo…...

python基础---基础运算
基础运算 可以使用type获取一个变量的类型 常见的数据类型 整形, 可以存储任意大小的整数, 支持二进制(如0b100,换算成十进制是4)、八进制(如0o100,换算成十进制是64)、十进制(100)…...
【数学】泰勒公式
目录 引言 一、泰勒公式 1.泰勒公式及推导 (1)推导 (2)公式 2.泰勒中值定理 (1)定理1(佩亚诺余项) (2)定理2(拉格朗日余项) …...

C++基础-编程练习题及答案
文章目录 前言一、查找“支撑数”二、数组元素的查找三、爬楼梯四、数字交换五、找高于平均分的人 前言 C基础-编程练习题和答案 一、查找“支撑数” 【试题描述】 在已知一组整数中, 有这样一种数非常怪, 它们不在第一个, 也不在最后一个&…...