网络原理(上)

news2024/12/25 10:06:29

  前言👀~

上一章我们介绍了网络的一些基础知识,今天来讲解一下网络原理相关的知识点,分三篇进行阐述内容有点多​​​​​​​

再谈协议分层

应用层

传输层(重点)

UDP协议

TCP协议

TCP如何完成可靠传输?(重点)

1.确认应答

2.超时重传

3.连接管理

4.滑动窗口

5.流量控制

6.拥塞控制

7.延时应答

8.捎带应答

9.面向字节流

10.异常情况的处理


如果各位对文章的内容感兴趣的话,请点点小赞,关注一手不迷路,讲解的内容我会搭配我的理解用我自己的话去解释如果有什么问题的话,欢迎各位评论纠正 🤞🤞🤞

12b46cd836b7495695ce3560ea45749c.jpeg

个人主页:N_0050-CSDN博客

相关专栏:java SE_N_0050的博客-CSDN博客  java数据结构_N_0050的博客-CSDN博客  java EE_N_0050的博客-CSDN博客


再谈协议分层

协议就是一种约定的格式,约定相同的数据格式,主要目的是为了让接收端在解析的时候明确如何解析数据中的各个字段,报文格式就按一定的规则进行拼接

应用层

应用层的协议,有现成的例如HTTP协议(超文本传输协议)下一篇详细讲解,但是很多时候都是我们自己去定义。自定义协议就是咋们在代码中规定好,这个数据如何传输,根据需求确认传输的信息,约定好信息按什么格式来组织

例子:打开外卖软件,相当于发起一个请求带有用户信息和位置信息,然后看到商家列表,这里就涉及程序和服务器之间的网络通信交互。这样服务器就根据请求中带有的信息进行处理然后返回响应(商家列表,每个商家包含头像、名称、地址等)

开发中常见的格式:

1.xml

很早之前xml来组织数据的(通过标签来组织数据)。后面开发中使用Mybatis时使用这种格式来写SQL语句,还有maven是使用xml格式来管理项目配置

HTML是xml的变种,xml是通用的数据格式,我们可以自定义。HTML是专属的数据格式,标签都定义好了的

xml的特点:数据的可读性更好,但是标签写起来繁琐,传输的时候会占用更多网络带宽

2.json

现在最流行的数据组织格式,键值对结构(key-value),{}使用花括号把所有的键值对括起来,键值对之间用逗号隔开,键和值之间用:分号隔开,键固定是String类型,值不固定可字符串可数字

json的特点:可读性好,比xml更简洁,和xml一样传输的时候会占用更多网络带宽(key也需要进行传输)

3.protobuffer(pb)

使用二进制的方式组织数据,保证带宽占用最低(把传递的信息按二进制形式进行压缩)

pb的特点:占用带宽最低,传输效率最高,适合性能要求高的场景,但是可读性不好


传输层(重点)

面试考点,工作常用的内容,以下是传输层主要协议,不是单单只有这两个协议

UDP:无连接、不可靠、面向数据报、全双工

TCP:有连接、可靠、面向字节流、全双工

这里补充一些区别:首先就是可靠传输的场景使用TCP更适合,TCP适用绝大部分场景。如果注重效率可靠性不敏感的话可以采用UDP进行传输,例如局域网内部(一个机房)的主机进行通信。然后就是传输数据包大小比较大的情况先考虑TCP,因为UDP限制死了64KB。如果要进行广播传输,优先UDP它天然支持,TCP需要额外代码实现

写一个服务器需要指定端口号,客户端是系统随机分配的端口号,端口号前面说过占2个字节,范围0-65535,0-1023知名端口号,1023-65535普通端口号

22:ssh服务器的端口号,ssh协议是用来登录远程主机的

80:http服务器的端口号

443:https服务器的端口号


UDP协议

UDP报文格式:

分为两段UDP报头和UDP载荷(payload)数据部分,载荷部分存储完整的应用层数据报。报头和载荷之间是字符串拼接,这个字符串这里是二进制数据。UDP报头分为四个部分(每部分2个字节),源端口号、目的端口号、UDP报文长度、UDP的校验和(checksum)

UDP报文长度:报头+载荷,2个字节(byte),16位(bit)表示的数据,表示的范围0-65535,换算为64KB,所以UDP数据报最长为64KB,所以数据报很大的时候就不好用UDP表示了,可以拆分位多个UDP数据报,但还是建议使用TCP(没有包大小的限制)

UDP携带数据的长度,确实是64KB-8,但是差距不大可以直接说64KB

校验和:在网络传输中,可能会收到外界的干扰,数据可能被破坏,可能某个地方传输是低电平,被干扰后成了高电平。使用校验和去检查,能够识别 出 出错的数据

校验和,本质是一个字符串,通过原始的数据生成的,并且体积比原始数据小,原始数据相同,得到的检验和就一定相同,反之检验和相同,原始数据大概率相同

如何基于校验和来完成数据校验?

1.发送方把发送的数据整理好(data1)通过算法计算出校验和(checksum1),之后同一发出

2.接收方收到数据data2(可能和data1不一样)和校验和(checksum1),然后通过相同算法重新计算校验和,得到校验和(checksum2),判断相不相同

3.如果相同,则data1和data2大概率相同。如果不同则肯定不同

校验和怎么计算?

此处UDP中使用的是CRC算法(循环冗余算法),把当前要计算校验和的数据,每个字节进行累加,把结果保存到两个字节变量中,溢出也没关系。如果中间某个数据出现传输错误,第二次计算的校验和 和第一次不同


MD5算法(工作常用):

特点:

1.定长:不管原始数据多长,计算出的MD5值,都是固定长度(16位)

2.分散:给你两个原始数据,只要其中一个字节不同,得到的MD5值差异会很大。所以看到这点能看出MD5也适合作为hash算法

3.不可逆:给一个原始数据,计算MD5容易,但是还原难,计算量大


TCP协议

TCP最大的特点就是可靠传输

TCP报文格式:


4位首部长度:描述了整个TCP报头长度有多长,注意是可变长的(主要是有个选项),这个首部其实就是指报头(header)一个数据报=首部(报头header)+载荷报头最短是20字节(没有选项),最长是60字节(选项最多是40字节)

保留位:图中写的英文字母,后续会用到进行讲解

选项:通过这个可以调整TCP报文长度选项是4个字节一个单位,不会出现1一个字节为一个单位这种),在这个选项中还包含"窗口扩展因子"

包含在报头内的16位校验和16位端口号这些和UDP一样


TCP如何完成可靠传输?(重点)

1.确认应答

实现可靠传输的核心机制,借助其他机制辅助完成可靠传输!!!

发送方发送数据的后,接收方收到数据后就会给发送方返回一个应答报文(ACK),发送方通过整个ACK可以确认自己数据是否发送成功

发送消息,在网络传输过程中可能出现后发先至的情况,一个数据包在传输的过程中,走的路线是很复杂的,不同数据包可能走不同的路线,也就是后发的消息比先发的消息先到。

TCP会在此处给数据包进行标识:

1.确保应答报文和发出的数据能对上号

2.确保出现后发先至的情况,能够让应用程序仍然按正确的顺序处理数据(接收缓冲区会去处理)

此时就靠TCP报头中的32位序号和32位确认序号

TCP将每个字节的数据都进行了编号,即为序列号每一个ACK都带有对应的确认序列号,这个序号就是一个整数,按照字节来编号的,用来描述数据的先后顺序

序号:一个TCP数据包中,例如有1000个字节的载荷数据,如果第一个字节的序号是1,记录在TCP报头的序号字段也就写1,所以TCP报头的序号字段是根据第一个字节序号来写的。并且只记录一个,什么意思呢?例如1000个字节最后一个字节序号自然是1000,但是在TCP报头中不会记录,只会记录第一个字节的序号,剩下的依次推理出来

确认序号:此时ACK也就是应答报文会在 确认序号 字段填写1001,这个1001是根据数据最后一个字节的序号+1得出,表示它收到发来的从1-1000个字节的数据并且希望发送方从这个序号开始传输,然后发回1001向发送方确认自己收到了这些数据,并且等待下一次数据的接收。接着发送方下次发送数据的第一个字节的序号从1001开始进行发送,接收方和上面一样,根据数据最后一个字节的序号+1得出确认序号接着发回,以此类推


所以发送方可以通过ACK数据包发送的确认序号来确认哪些数据被确认收到了,也就是TCP的特点可靠传输

接着有个问题然后区分数据包是普通数据还是ACK答应报文数据?

TCP报头中的保留位字段中的第二位(ACK)来确认

如果是1表示数据包是一个答应报文,此时该数据包中的确认序号生效,如果是0表示数据包是一个普通报文,此时该数据包中的确认序号不生效

确认序号的规则为什么是最后一个字节的序号+1表示?结合滑动窗口进行去理解


2.超时重传

如果网络传输过程中出现丢包,发送方接收不到ACK,此时使用超时重传机制,针对确认应答进行补充

丢包:类似收费站,节假日堵车了就只能等(路由器/交换机会出现)。对于路由器来说出现这种情况,它会直接把其中的大部分数据包直接丢了,此时这些数据包就在网络上消失了。丢包的概率取决于网络基础设施和网络环境

丢包会有两种情况:

1.传输的数据丢了

2.返回的ACK丢了

无论上述出现哪种情况,发送方都会进行"重传",牺牲的是传输效率,但是提升了数据能被传过去的概率

发送方何时进行重传?等待时间

发送方发送数据之后,会等待一段时间,如果此时ack来了,就视为数据到达。如果达到这个时间数据没来,就触发重传机制如果重传次数多了,丢包概率估计不小,此时估计是网络出现问题了

等待时间等多久?

1.初始的等待时间可以配置的,不同操作系统定的不一样,也可以通过修改一些内核的参数来引起这里的时间变化

2.等待的时间是动态变化的,随着超时的次数,等待时间会越长

3.随着等待时间的拉长,TCP认为网络或者对端主机出现异常,强制关闭连接(准确的说会触发TCP的重置连接)

如何解决重复数据以及顺序排列?

如果主机A给另外一台接收发送数据后,此时主机B收到了数据但是发送ack的出现丢包,主机A过了等待时间又发送数据,主机B会收到很多重复数据。

TCP有个接收缓冲区,属于我们主机内存中分配的,接收缓冲区会识别并且处理重复数据包,直接丢弃并且会根据TCP报头中的序列号对数据包进行排序,确保数据包按照发送顺序排列。即使数据包按乱序到达,缓冲区也能将它们重新排序。也就是解决上面说的后发先至的问题


3.连接管理

建立连接和断开连接,也就是三次握手和四次挥手(面试经典问题),把握手想象成打招呼,tcp这里的握手,就是给对方传输一个简短的没有业务数据的数据包,通过这个数据包唤起对方注意,从而触发后续操作

三次握手:

TCP的三次握手,TCP在建立连接的过程中,需要通信双方一共打"三次招呼"才能建立连接。并且建立连接一般都是客户端主动发起

例如客户端A想和服务器B建立连接,下面有图

1.客户端A发送一个简短的没有业务数据的数据包(SYN,同步报文段segement)SYN:一个特殊的TCP数据包,没有载荷的(不携带业务数据的,业务数据就是应用层数据包)

2.服务器B收到SYN后,就会返回一个ACK应答报文,接着再发一个SYN。然后客户端A收到后,再返回一个ACK应答报文,此时握手完成,双方就记录了对方的信息。

B传回SYN和ACK可以合为一次。其实建立连接的过程就是双方都需要发起SYN,以及反馈一个ACK,一共是四次握手,但是中间两次可以合并成一次,这里能合并是因为ACK和第二个SYN是系统内核触发的,所以同一个时机可合并

三次握手是要解决什么问题?

还是那句话TCP初心就是为了实现可靠传输,进行确认应答和超时重传的前提是网络环境是良好的顺畅的,如果网络出现问题,可靠传输就无从谈起

三次握手核心作用?

1.投石问路,确认当前网络是否通畅

2.要让发送方和接收方都能确认自己的发送能力和接收能力,例如开黑的时候双方通过简单的交流,检查麦克风和耳机检查双方的通信能力

3.让通信双方,在握手过程中,针对一些重要参数,进行协商。上面说到的tcp通信过程的序号从几开始就是双方协商出来的(一般不是从1开始的)。有时候网络环境不好的时候会出现断连,再重新建立连接。重连的时候可能等太久,以至于直接建立新的连接,此时旧的连接才来,这时候应该把旧的连接丢了

通过四次握手是否可行?通过两次握手是否可行?

四次握手可以但没必要,两个数据合并一个数据效率更高。两次握手不行,例如服务器发送完SYN和ACK后,客户端是知道了这边的情况,但是服务器不确定客户端的情况

TCP协议下,服务器和客户端状态

四次挥手:

断开连接,客户端和服务器都可以主动发起。例如A要想和B断开连接就尝试发送一个FIN(结束报文段)这个FIN是标志位第六位,如果为1就是一个结束报文段,0则不是。然后B接收到FIN,就给A返回一个ACK,还要返回一个FIN,然后A也要返回给B一个ACK,此时完成断开连接,双方把对端信息删除

这里和三次握手不同,此处的四次握手,不一定把中间的两次交互合二为一,为什么?

原因:ACK和第二个FIN的触发时机不同,ACK是内核响应的,B收到FIN会立即返回ACK,第二个FIN是应用代码触发的,B这边调用close方法才会触发FIN(也是内核完成的)。也就是服务器收到FIN同时返回ACK,再执行到close方法的地方发起FIN,这里要经历一些时间,不确定多久时间,具体多少要结合代码这里TCP有一个机制有几率合并(延时应答)拖延ACK的回应时间,这样就有机会和下一个FIN合并

TIME_WAIT状态:

哪一方主动发起断开连接,哪一方就会进入TIME_WAIT状态

先说如果没有这个状态会发现什么样的情况,可能B发送FIN后,A立马close了,导致B这边没接收ACK,以为出现丢包触发超时重传,达到一定程度会直接断开连接。虽然还是会断开,但是浪费时间还有额外的开销。所以有了TIME_WAIT状态,就能进行等待重传的FIN发来,防止最后一个ACK丢包

TIME_WAIT等待多久?

如果网络上两个节点通信消耗的最大时间为MSL,此时TIME_WAIT的时间就是2*MSLMSL译为“最长报文段寿命”,它是任何报文在网络上存在的最长的最长时间,超过这个时间报文将被丢弃,这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段


4.滑动窗口

TCP的可靠传输会影响传输效率,多了ACK等待时间,单位时间内传输的数据就减少了。并且我们知道TCP的可靠性传输效率不如UDP不可靠的传输效率,所以我们使用滑动窗口来减小可靠传输对性能的影响,来缩小和UDP的差距

缩短确认应答的等待时间,批量传输数据:不等待ack回来,直接再发下一个数据,批量传输不是"无限"传输,是有上限的,达到上限之后再统一等待ACK。不等待的情况下,批量最多发多少数据,这个数据量称为窗口大小,假设A给B批量发送了四份数据达到了上限,此时要等B这边发来对应的ACK后才能继续发送,此时A收到一个ACK回来就接着发一个过去,发两个几个就发几个过去。窗口越大,等待ACK越多,传输效率越高注意不是窗口设置越大越好,此时传输速度过快导致接收方处理不过来,导致丢包的概率增加。所以要建立在可靠性的基础上提高效率

出现丢包如何解决,超时重传?

有下面两个情况:

1.数据包已经抵达,ACK丢了

这种情况,不需要任何重传也是没事的。因为确认序号表示序号之前的数据收到了,下一个从确认序号进行发送,如果出现ACK丢包,我收到了第二个数据包或第三个第四个数据包,没事我从最后一个数据包的序号+1进行发送这个确认序号就涵盖了之前数据的序号。如果ACK全丢了,说明丢包率100%,可能你家网线被嘎了

2.数据包丢了

A这边需要知道丢的是哪个数据包,B这边告诉A哪个数据包丢了

下图A批量发送数据的时候,中途有一个数据包出现丢包B这边就没收到这个数据包,就向A不断的索要这个数据包,然后A收到B不断的索要的数据包是哪个,A就知道哪个数据包丢了然后重传,B收到后,返回一个ACK这个ACK的确认序号就是A发来的最后一个数据包的序号+1


上述的重传整个过程是很快的,快速重传属于超时重传的变种。如果通信双方,传输数据量小也不频繁,就是普通确认应答和超时重传。如果传输数据量大且频繁,则进入滑动窗口模式,按快速重传处理丢包


5.流量控制

站在接收方的角度,限制发送方的传输速度。就是控制发送数据的那方速度不能快过接收数据方处理速度

怎么限制呢?先了解以下内容

前面提到接收缓冲区,这个接收缓冲区属于是内存的一部分,那也就说明这玩意属于操作系统内核可以控制,当发送数据过来会存到接收缓冲区中,然后服务器从接收缓冲区读取出来进行处理,读取出来后这个数据在接收缓冲区就被删除了,所以可以把接收缓冲区看作是一个阻塞队列,然后整体结合发送方和接收方就是生产者消费模型。对于消费者的速度取决于代码怎么写的。对于处理能力可以通过接收缓冲区的空间大小,来衡量处理能力。空间越大,消费越快,处理能力越强,反之则弱

如何进行限制呢?接收端如何把窗口大小(也可以说接收缓冲区剩余空间大小)告诉发送端呢?

接收方每次接收数据后,把接收缓冲区剩余空间大小通过ACK返回给发送方发送方就能参考这个大小来调整下一次的发送速度。回忆我们的TCP首部中,有一个16位窗口字段,接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 "窗口大小" 字段,接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端这里上面写着16位窗口大小也就是64KB,16位数字最大表示65535,那么TCP窗口最大就是65535字节么?这个(在TCP报头中)选项中还包含"窗口扩展因子",通过扩展因子M 让 窗口字段的值左移 M位就可以让窗口大小表示更大的值,左移1位也就是乘2。如果接收端缓冲区满了,就会将窗口置为0。这时发送方不再发送数据,会进入等待,等多久呢?窗口探测,发送方会定期发送一个窗口探测包(不携带业务数据),为了触发ACK,让接收端把接收缓冲区剩余空间大小告诉发送端


总结:流量控制搭配滑动窗口来保证效率的同时考虑接收方的处理能力


6.拥塞控制

刚才流量控制考虑的是接收方的处理能力,但实际我们还需要考虑整个通信的路径,任何一个节点处理能力上限的话都有可能会影响到可靠传输,也是和刚才的滑动窗口和流量控制一起的,拥塞控制则是用来考虑/衡量通信过程中各节点的情况

关键问题:由于中间节点结构复杂,不只是处理当当一个接收方和发送方的数据,所以我们使用"实验"的方式来找到合适的值

如何解决?

1.例如发送方A要发送数据,此时TCP引入 慢启动 机制让A先按比较小的速率发送数据(小的拥塞窗口),如果数据传输的过程很顺利没有出现丢包的情况,就尝试使用更大的拥塞窗口,更大的速率进行发送(指数增长,翻倍)

2.当指数增长过程中,如果达到阈值,就会转为线性增长,每次加固定值。但还是属于是增长速度也快,随着拥塞窗口大小的不断增大,达到一定程度,中间节点可能出现丢包的情况,这时候发送方发现丢包了,就将拥塞窗口大小调小。重新按慢开始->指数增长->线性增长的方式进行调整,并且根据丢包的窗口大小,重新定指数增长的阈值,避免增长的太快又立马出现丢包的情况。如果还是出现丢包,则再将拥塞窗口调小,如果没出现丢包则尝试将拥塞窗口调大。类似敌退我进,敌进我退。整个过中程发送方不断调整大小,来找到中间节点的瓶颈


想象谈恋爱的过程,从刚开始慢慢来,然后进入热恋期,蹭蹭的往上涨。随着时间的过去,达到一定程度,这个速度就会慢下来,趋于平稳。此时两个人发生冲突,然后之间的感情就受到影响,速度又进一步降下来。等冲突解决了和好了,这时候那感觉大家都懂吧,又很好了这个速度和感情又趋于正轨。整个过程就类似这样

经典版是出现丢包一下速度降的太低了,新版则是仍然有一定的初始速度,因为确定了这里出现丢包的概率很低,以此来提高效率。还是想象谈恋爱的过程
 

总结:流量控制和拥塞控制都是限制了窗口的大小,最终窗口的大小,是取两者之间的较小值,就是采取低的那方,稳健点


7.延时应答

正常情况,A传数据给B,B立刻回ACK给A。但有的时候A传数据给B的时候,B不会立刻回ACK给A,而是等一会再回(延时应答),也属于是提高效率的一个机制,因为发送方的窗口大小是传输效率的关键

什么意思呢?前面流量控制可以限制发送方的传输速率,来保证接收方能处理过来。延时应答能让这个窗口变大些并且速率快些,通过延时返回ACK,接收方有足够的时间处理数据,这样缓冲区的剩余空间也会维持一个比较充足的大小,所以返回的窗口大小也会大些。例如A传输了5k数据,B接收了5K数据,然后延时返回ACK,能有充足的时间处理数据。此时A又传输了2k数据,此时接收方处于延时的期间,可以把这部分数据也进行处理然后把刚才5k的数据处理完再返回ACK,此时窗口大小就会 相对于立即返回ACK大些,看下面的图对比之前的图

总结:延时应答和捎带应答搭配,能促成四次挥手能变成三次挥手


8.捎带应答

在延时应答的基础上,又进一步提高效率。前提是要有延时应答这个机制才促成了捎带应答

怎么提高呢?就是A向B发送一个请求,B这边接收请求后本来会返回一个ACK给A,但是由于延时应答机制,所以延时返回ACK。此时B这边处理请求后要返回一个响应,这时候顺便带上ACK一同返回。这样的情况能提高效率,为什么呢?因为如果一个一个传的话数据包要分开封装分用,此处就把两个数据包一起封装分用,就合二为一,并且在四次挥手说过不一定能像三次握手一样合并,这个机制就有一定可能


9.面向字节流

面向字节流会有一个重要的问题,粘包问题。(面向字节流的机制都有类似情况,不是TCP独有)

粘包:此处的包是应用数据包,如果同时有多个应用层数据包被传输,就可能会出现粘包。由于是面向字节流,传输的数据是以字节为单位,并且TCP可以传输多个应用层数据包,此时接收缓冲区这多个应用层数据包则以字节的形式黏在一起,应用程序读取的时候就不知道哪里到哪里是一个完整的数据

UDP则不会出现粘包这种问题,因为UDP是面向数据报的通信方式,以数据报为传输单位!

网络编程这一篇我没整理有时间再整理,之前的UDP服务器和客户端传请求和响应都是装到一个DatagramPacket对象中进行传输,在UDP的接收缓冲区中相当于一个一个DatagramPacket对象,应用程序读取的时候就知道哪里到哪里是一个完整的数据

如何解决粘包问题呢?

核心:通过定义好应用层协议,明确应用层数据包之间的边界

1.引入分隔符:

这个很简单就比如我们平常发消息给对方,敲完了消息是不是要一个回车或者发送,此时不管你发送多个还是一个都带有分隔符,这样读取的时候读到分隔符为止就是一个应用层数据包


2.引入长度:

通过在数据包的前面加个长度字段,这样接收方在读取的时候就知道每个数据包的长度,例如发来的数据包长度是3字节,接收方先读取前两个字节得出长度,然后进一步读取数据,读取3个字节后就是一个应用层数据包,然后接着以这样的方式进行读取


10.异常情况的处理

使用TCP出现 以下情况 如何处理?

1.进程崩溃:

这个情况进程异常终止了,文件描述符表被释放了,相当于调用了Socket.close,这时候就会触发FIN,对方收到后也会发回FIN和ACK,接着返回最后一个ACK,完成四次挥手断开连接。虽然进程没了,但是TCP的连接可不一定没,可以独立于进程存在

2.主机关机:

我们在关机的时候,系统会触发终止进程的操作(相当于上面的进程崩溃),先强制把所有的进程都关了,然后资源啥的都释放,然后关机。在终止进程的时候,就触发FIN,然后同样的执行四次挥手。但是如果系统关闭的晚还能执行完成四次挥手,如果关闭的早了,可能收到对端的FIN和ACK,然后就关闭了。对端以为丢包了,然后接着发,到了一定程度就不发了,直接就断开连接(删除对端的信息)

3.主机掉电:

台式机直接拔电源,直接黑了,不会像上面关机那样的流程直接就嘎了,都来不及发FIN,针对这种会有两种情况

        1.接收方主机掉电

如果发送方发送数据,接收方主机掉电,会先等待然后触发超时重传,重传几次还是没反应,就触发TCP连接重置,发起复位报文段,保留位的第4位(RST),如果这个复位报文段发去之后,没效果直接就断开连接了

        2.发送方主机掉电

如果接收方等待接收数据,此时发送方主机掉电,接收方就判断不出是发送方是没发消息还是主机掉电。此时TCP触发心跳包的机制,接收方会周期性的给发送方发起一个特殊的数据包(不携带业务数据),等待返回一个ACK。如果发送多次没反应,就认为对方没了,直接断开连接


4.网线断开:

和主机掉电类似,接收方掉电就触发超时重传->触发TCP连接重置->没反应断开连接,发送方主机掉电就触发心跳包->没反应断开连接

心跳机制:在日常开发中比较常见,如何识别一台机器挂了,就可以使用这个机制,但是不是使用TCP的心跳机制(周期长),我们自己手动去实现(这里希望是秒级或毫秒级识别对端状态)

上述是TCP中十个比较重要的机制,不是TCP只有十个机制!!!

以上便是本章内容,这章内容很重要,不管是面试还是工作都需要掌握,后面还有HTTP协议也很重要,内容有点多分着讲我们下一章再见💕

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

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

相关文章

在 PostgreSQL 里如何处理数据的归档和清理过程中的数据完整性验证?

🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会!📚领书:PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 里如何处理数据的归档和清理过程中的数据完整性验证 在 PostgreSQL 里如何处理数据的归…

3D数字孪生项目运行卡顿,来看看它要求的电脑配置。

有些小伙伴和我说,数字孪生项目运行卡顿,不知道啥原因,根源还是这类项目是浏览器渲染,对电脑配置要求很高。 运行3D数字孪生项目需要一台性能强大的电脑, 以下是一个推荐的配置清单: 1. 处理器&#xff1…

css实现每个小盒子占32%,超出就换行

代码 <div class"visitors"><visitor class"item" v-for"(user,index) in userArr" :key"user.id" :user"user" :index"index"></visitor></div><style lang"scss" scoped&…

Porfinet转DeviceNet主总线协议转换网关

产品功能 1. 远创智控YC-DNTM-PN型网关是Porfinet从转Devicenet主工业级Porfinet网关。‌这种网关设备允许将Porfinet网络中的设备连接到Devicenet网络中&#xff0c;‌从而实现不同工业通信协议之间的互操作性。‌这些网关设备通常具有两个以太网接口&#xff0c;‌分别用于连…

shell脚本-linux如何在脚本中远程到一台linux机器并执行命令

需求&#xff1a;我们需要从11.0.1.17远程到11.0.1.16上执行命令 实现&#xff1a; 1.让11.0.1.17 可以免密登录到11.0.1.16 [rootlocalhost ~]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created d…

Ubuntu 22.04.4 LTS (linux) 安装iftop 监控网卡流量 软件

1 安装iftop sudo apt update sudo apt-get install iftop 2 监控网卡 sudo iftop -i eth0 -n -p 界面最上面&#xff0c;显示的是类似刻度尺的刻度范围&#xff0c;显示流量图形的长条作标尺用的。 中间的< >这两个左右箭头&#xff0c;表示的是流量的进出方向.TX&…

使用JS和CSS制作的小案例(day二)

一、写在开头 本项目是从github上摘取&#xff0c;自己练习使用后分享&#xff0c;方便登录github的小伙伴可以看本篇文章 50项目50天​编辑https://github.com/bradtraversy/50projects50dayshttps://github.com/bradtraversy/50projects50days有兴趣的小伙伴可以自己去gith…

美式键盘 QWERTY 布局的起源

注&#xff1a;机翻&#xff0c;未校对。 The QWERTY Keyboard Is Tech’s Biggest Unsolved Mystery QWERTY 键盘是科技界最大的未解之谜 It’s on your computer keyboard and your smartphone screen: QWERTY, the first six letters of the top row of the standard keybo…

Redis的热key解决

1、Redis热Key会带来哪些问题 1、流量集中&#xff0c;达到物理网卡上限。 当某一热点 Key 的请求在某一主机上超过该主机网卡上限时&#xff0c;由于流量的过度集中&#xff0c;会导致服务器中其它服务无法进行。 2、请求过多&#xff0c;缓存分片服务被打垮。 如果热点过于…

Linux入门笔记(指令)

操作系统是什么&#xff1f; 操作系统是一款做软硬件管理的软件。计算机系统自下而上可以大致分为4部分&#xff1a;硬件、操作系统、应用程序和用户。操作系统管理各种计算机硬件&#xff0c;为应用程序提供基础&#xff0c;并且充当计算机硬件与用户之间的中介。重点&#x…

泛微e-cology WorkflowServiceXml SQL注入漏洞(POC)

漏洞描述&#xff1a; 泛微 e-cology 是泛微公司开发的协同管理应用平台。泛微 e-cology v10.64.1的/services/接口默认对内网暴露&#xff0c;用于服务调用&#xff0c;未经身份认证的攻击者可向 /services/WorkflowServiceXml 接口发送恶意的SOAP请求进行SQL注入&#xff0c;…

高并发项目(一):内存池的概念/定长内存池的实现

目录 一、池化技术及其优势 1.1什么是池化技术 1.2内存池的作用 1.3malloc的原理 二、定长内存池的实现 一、池化技术及其优势 1.1什么是池化技术 所谓 “ 池化技术 ” &#xff0c;就是程序先向系统申请过量的资源&#xff0c;然后自己管理&#xff0c;以备不时之需。之所…

微调 Florence-2 - 微软的尖端视觉语言模型

Florence-2 是微软于 2024 年 6 月发布的一个基础视觉语言模型。该模型极具吸引力&#xff0c;因为它尺寸很小 (0.2B 及 0.7B) 且在各种计算机视觉和视觉语言任务上表现出色。 Florence 开箱即用支持多种类型的任务&#xff0c;包括: 看图说话、目标检测、OCR 等等。虽然覆盖面…

吴恩达大模型系列课程《Prompt Compression and Query Optimization》中文学习打开方式

Prompt Compression and Query Optimization GPT-4o详细中文注释的Colab观看视频1 浏览器下载插件2 打开官方视频 GPT-4o详细中文注释的Colab 中文注释链接&#xff1a;https://github.com/Czi24/Awesome-MLLM-LLM-Colab/tree/master/Courses/Prompt-Compression-and-Query-Op…

Activity工作流框架——生成数据表

自动生成activiti数据库表 首先第一步&#xff0c;引入activiti依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency>&…

生成树(STP)协议

一、生成树的技术背景 1、交换机单线路上链,存在单点故障,上行线路及设备都不具备冗余性,一旦链路或上行设备发生故障,网络将面临断网。 总结:以下网络不够健壮,不具备冗余性。 2、因此引入如下网络拓扑结构: 上述冗余拓扑能够解决单点故障问题,但同时冗拓扑也带来了…

Google 数据中心繁忙运转的一天

Google 数据中心是互联网世界的基石&#xff0c;支撑着搜索引擎、云计算服务、视频流媒体等无数在线应用的正常运行。 早晨&#xff1a;启动与检查 6:00 AM - 早班员工到岗 数据中心的运维团队分为多个班次&#xff0c;早班员工准时到岗。他们首先查看夜班同事的交接记录&…

C语言 | Leetcode C语言题解之第238题除自身以外的数组的乘积

题目&#xff1a; 题解&#xff1a; // 数组中除自身以外元素的乘积 int* productExceptSelf(int* nums, int numsSize, int* returnSize) {static int ra[100000]; // 结果数组for (int i 0; i < numsSize; i) {ra[i] 1; // 初始化结果数组为1}int pre 1, suf 1; /…

迭代器+反向迭代器

接上节内容&#xff0c;反向迭代器&#xff08;aoto的价值显示的更明显&#xff09; int main() {string s1("hello world");//string::reverse_iterator rit s1.rbegin();auto rit s1.rbegin();while (rit ! s1.rend()){(*rit) 3;cout << *rit << &…

TypeScript 函数类型 (二)

函数类型 函数有两种方式定义 function 关键字来定义函数 function a(){}表达式定义&#xff08;箭头函数的形式&#xff09; const a()>{}函数需要定义类型的有三个地方 入参 和 返回值 以及 函数本身 的类型, 函数本身的类型常用于表达式定义的函数 function sum(a:stri…