面试突击69:TCP 可靠吗?为什么?

a5fe91ffa771e0361b8aa6127c769466.jpeg

作者 | 磊哥

来源 | Java面试真题解析(ID:aimianshi666)

转载请联系授权(微信ID:GG_Stone)

相比于 UDP 来说,TCP 的主要特性是三个:有连接、可靠、面向数据流。所谓的“有连接”指的是 TCP 中的连接管理机制,也就是著名的三次握手和四次挥手,就像打电话一样,想要正常的交流,必须先和对方建立起连接,这就是所谓的“有连接”,而面向数据流的机制咱们以后再讲,我们今天要讨论的主题是:TCP 是如何保证可靠性的?TCP 之所以能保证可靠性,主要是通过以下 6 个手段:

  1. 校验和

  2. 确认应答

  3. 超时重传

  4. 流量控制

  5. 拥塞控制

  6. 丢弃重复数据

接下来,我们详细来看这几种手段的具体实现。

1.校验和

TCP 协议的数据格式如下图所示:c26126147cf35ff687a534a16b4bf83a.png(图片来源:许许如生xxrs) 从上图可以看出“校验和”是保存在 TCP 首部中的一个数据,TCP 的发送端和接收端会采用相同的算法,根据发送的数据计算出一个 16 位的校验和,并且校验和会连同数据一起发送给接收端。接收端在得到数据之后,会根据接收的数据生成一个新的校验和,然后用新的校验和与传递过来的校验和做对比,如果校验和相同,那么说明数据在传递过程中没有发生任何改变,是一个有效的数据,反之则为无效数据,舍弃即可。

校验和基本算法

TCP/UDP/IP 等协议的校验和算法都是相同的,采用的都是将数据流视为 16 位整数流进行重复叠加计算。为了计算检验和,首先把检验和字段置为 0,然后,对有效数据范围内中每个 16 位进行二进制反码求和,结果存在检验和字段中,如果数据长度为奇数则补一字节 0。当收到数据后,同样对有效数据范围中每个 16 位数进行二进制反码的求和。由于接收方在计算过程中包含了发送方存在首部中的检验和,因此,如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该为全 0 或全 1(具体看实现了,本质一样) 。如果结果不是全 0 或全 1,那么表示数据错误。

2.确认应答

确认应答机制是保证消息传递可靠性的关键手段,也是几乎所有消息中间件(MQ)中,最常用的技术之一,比如主流的消息中间件 RabbitMQ、Kafka、RocketMQ 中都有确认应答机制,也就是我们常说的 ACK(ACKnowledge Character,确认字符)。确认应答机制是 TCP 中,保证消息可靠性的核心机制。怎么才能确认你发的消息对方一定收到了呢?最有效的手段无疑是对方告诉你,它已经收到了,这就是确认应答。确认应答的流程如下图所示:5f54dba51edd6d9be6f97cc613256c4c.png

3.超时重传

消息在确认应答的过程中可能会出现两个问题:第一,消息在发送的时候丢失了,第二,消息在确认应答时丢失了,如下图所示:9fa2e28f44244ecd43e1d65f107852ce.png显然,即使有了确认应答机制也保证不了消息不丢失,那怎么办呢?消息丢了没关系,发送端在确认了消息丢失之后,再补偿一个同样的消息给接收端不就解决了?这就是超时重传机制。

巧妙的超时重传机制

TCP 的超时重传机制在设计上也非常巧妙,它为了保证消息在任何环境中,都能高效的通讯,所以 TCP 采用的是“动态时间”的超时重传机制。比如第一次如果消息丢了,那么发送端会在 500ms 之后再发送一个消息,如果发送的第二个消息也丢了,那么发送端会在 1000ms 之后再发送一个消息,如果第三个消息也丢了,那么它会在 2000ms 之后再发送一个消息,如果累计了一定的次数,消息还没有成功的发送,那么 TCP 会认为对方主机存在异常,会强制关闭连接,这就是 TCP 超时重传的主要执行流程。

4.流量控制

接收端处理数据的速度是有限的,如果发送端发的太快,那么就会导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。因此 TCP 会根据接收端的处理情况,动态调整发送数据的大小,这个机制就叫流量控制(Flow Control)。

5.拥塞控制

拥塞控制指的是 TCP 会根据当前网络的情况,动态的控制发送数据的多少,以适合的速度来传递数据。想象一下,如果 TCP 在不清楚网络情况的环境下,贸然的发送大量的数据给接收端,这样就会导致更多的丢包及超时重传,从而引起一系列的连锁反应,导致数据传递变慢。而 TCP 采取的是“慢启动”机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据,这就是拥塞控制机制。如果传递的数据多了,出现了大量的丢包,那么 TCP 会将发送的数据量调小,然后再尝试慢慢的增加发送的数据量,通过这种动态发送数据包的形式,来实现适合当前网速的数据传递,这就是 TCP 拥塞控制的具体实现。

6.丢弃重复数据

通过前面的知识我们知道,在确认应答时,由于确认应答消息的丢失,那么接收方可能会收到发送方的重复数据,如下图所示:4dc2bd18701565a336d1171b379c6b38.png而此时对于业务方来说,只需要一个数据就可以了,所以 TCP 还有一个机制,丢弃重复数据的机制,这样就能保证业务方接收到的数据是正确的了。TCP 会给每一个发送的包上加上一个编号,如果接收到了编号相同的数据包,那么就说明接收端得到了重复的包,丢弃即可。

总结

TCP 保证可靠性的主要手段有 6 个:校验和、确认应答、超时重传、流量控制、拥塞控制、丢弃重复数据。其中流量控制和拥塞控制很容易搞混,我们要清楚的知道,流量控制是针对接收端接收能力的控制机制,而拥塞控制是针对当前网络的控制机制,所以千万不要搞混了。

参考 & 鸣谢

blog.csdn.net/namelcx/article/details/6866720

是非审之于己,毁誉听之于人,得失安之于数。

公众号:Java面试真题解析

面试合集:https://gitee.com/mydb/interview

71c8c922315d39c71e21496a92d0593d.gif

往期推荐

f202de51e8f9b592293bd60eb6d379e2.jpeg

面试突击68:为什么 TCP 需要 3 次握手?


c64577574498d51eed499b0fc53f7f44.jpeg

面试突击67:说一下 TCP/IP 协议?以及每层的作用?


1f564eb4036d1bad0e6f1ff09996ea37.jpeg

面试突击66:请求转发和请求重定向有什么区别?


12fe3bb8cd54fb93916382a886e9a8ca.gif

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

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

相关文章

vc++中画线时xor_C ++'xor_eq'关键字和示例

vc中画线时xor"xor_eq" is an inbuilt keyword that has been around since at least C98. It is an alternative to ^ (EXCLUSIVE-OR Assignment) operator and it mostly uses for bit manipulations. “ xor_eq”是一个内置关键字,至少从C 98起就存在…

【学习笔记】java核心技术学习笔记整理

《java核心技术》 花了半天到一天又认真读了一下java核心技术中的类部分,感觉最近编程时候好多迷迷糊糊,“这样对不对呢,试一试。怎么不对呢”这类的迷糊问题原来都早有定义。 main函数必须在主类中 一个class就是一个机器,要使…

Java 是值传递还是引用传递?

作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)开篇先来曝答案,在 Java 语言中,本质只有值传递,而无引用传递,解释和证明详见…

用于数据分析的Python – Pandas

大熊猫 (Pandas) Pandas is an open-source library built on top of NumPy Pandas是建立在NumPy之上的开源库 It allows for fast analysis and data cleaning and preparation 它允许快速分析以及数据清理和准备 It excels in performance and productivity 它在性能和生产力…

1022词法分析实验总结

经过这次词法分析的实验之后,收获良多。弥补了一些知识空洞,以前不懂的知识也弄懂了。 显然这都得力于组员之间的合作与帮助,一人负责编写,其他在旁边给想法同时学习。程序中运用了许多for,if,while等的循环…

SpringCloud基于RocketMQ实现分布式事务

前言分布式事务是在微服务开发中经常会遇到的一个问题,之前的文章中我们已经实现了利用Seata来实现强一致性事务,其实还有一种广为人知的方案就是利用消息队列来实现分布式事务,保证数据的最终一致性,也就是我们常说的柔性事务。消…

c# uri.host_C#| 具有示例的Uri.Host属性

c# uri.hostUri.Host属性 (Uri.Host Property) Uri.Host Property is the instance property of Uri class which used to get host components from URI. This property returns a string value. This property may generate System.InvalidOperationException exception. Uri…

VS使用和错误收集

USE: VS引用相对路径(需要说明的是,“..\”表示退出这一目录) VS 2005项目中添加lib库以及代码中的相对路径 ERROR: fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires M…

漫画:怎么证明sleep不释放锁,而wait释放锁?

wait 加锁示例public class WaitDemo {private static Object locker new Object();public static void main(String[] args) throws InterruptedException {WaitDemo waitDemo new WaitDemo();// 启动新线程,防止主线程被休眠new Thread(() -> {try {waitDemo…

机器学习 导论_机器学习导论

机器学习 导论什么是机器学习? (What is Machine Learning?) Machine learning can be vaguely defined as a computers ability to learn without being explicitly programmed, this, however, is an older definition of machine learning. A more modern defin…

就国内某个程序员问答网站的简单的分析

为什么80%的码农都做不了架构师?>>> 一、数据抓取 分析页面数据,设计数据表结构数据只要包含投票、回答数、问题状态、最后谁回答过、浏览数、问题标题、标签,数据样例如下:由于一开只打算爬问题标题,问题…

树的结构 数据结构_段树| 数据结构

树的结构 数据结构What is a segment tree? 什么是段树? A segment tree is a full binary tree where each node represents an interval. A node may store one or more data members of an interval which can be queried later. 段树是完整的二叉树&#xff0…

iOS开发中 常用枚举和常用的一些运算符(易错总结)

1、色值的随机值:#define kColorValue arc4random_uniform(256)/255.0 // arc4random_uniform(256)/255.0; 求出0.0~1.0之间的数字view.backgroundColor [UIColor colorWithRed:kColorValue green: kColorValue blue: kColorValue alpha: 0.5]; 2、定时器的使用&…

明明加了唯一索引,为什么还是产生重复数据?

前段时间我踩过一个坑:在mysql8的一张innodb引擎的表中,加了唯一索引,但最后发现数据竟然还是重复了。到底怎么回事呢?本文通过一次踩坑经历,聊聊唯一索引,一些有意思的知识点。1.还原问题现场前段时间&…

python字符串 切片_用于切片字符串的Python程序

python字符串 切片Given a string and number of characters (N), we have to slice and print the starting N characters from the given string using python program. 给定一个字符串和字符数( N ),我们必须使用python程序从给定的字符串中切片并打印开始的N个字…

nmap入门之主机发现

2019独角兽企业重金招聘Python工程师标准>>> #主机发现(HOST DISCOVERY) ##仅列出IP,不扫描 nmap -sL 192.168.70.0/24 > nmap_result.txt 2>&1##仅ping扫描,不扫描端口 nmap -sn 192.168.70.0/24##不ping扫…

面试官:为什么ConcurrentHashMap要放弃分段锁?

今天我们来讨论一下一个比较经典的面试题就是 ConcurrentHashMap 为什么放弃使用了分段锁,这个面试题阿粉相信很多人肯定觉得有点头疼,因为很少有人在开发中去研究这块的内容,今天阿粉就来给大家讲一下这个 ConcurrentHashMap 为什么在 JDK8 …

ruby .each_Ruby中带有示例的Array.each方法

ruby .eachRuby Array.each方法 (Ruby Array.each method) Array.each method can be easily termed as a method which helps you to iterate over the Array. This method first processes the first element then goes on the second and the process keeps on going on unt…

面试突击72:输入URL之后会执行什么流程?

作者 | 磊哥来源 | Java面试真题解析(ID:aimianshi666)转载请联系授权(微信ID:GG_Stone)在浏览器中输入 URL 之后,它会执行以下几个流程:执行 DNS 域名解析;封装 HTTP 请…

二层交换网络_网络中的第2层交换

二层交换网络二层交换简介 (Introduction to Layer 2 Switching) As you know hubs are not intelligent devices. Whenever a hub receives a frame, it broadcasts the frame in all ports. Also, the hub represents a single collision domain i.e. when any 2 hosts send …