第三十篇:TCP连接断开过程,从底层说明白,TCP系列五
上一篇《第二十九篇:图解TCP三次握手,看过不会忘,从底层说清楚,TCP系列四》说了TCP的三次握手,接下来我将讲解TCP四次挥手。
既然有连接就有断开,谈到这里,有的同学可能会想,不就是TCP的断开吗?简单,四次挥手解决问题,只要了解了四次的挥手过程就掌握了TCP的断开,我只能说:同学,too young,too simple;且让我提出几个问题去思考:
- 连接断开是谁先发起的?
- 如果断电/断网了,连接会断开吗?
- 程序奔溃了,连接会断开吗?
- 什么情况下没有四次挥手连接也会断开?
- 连接断开发生在应用层还是传输层?
只有掌握了断开的底层逻辑,才能在工作中遇到问题不慌不忙,做到游刃有余的解决问题,轻松拿高薪。
一、理想状态下,一个 TCP 连接可以被长期保持
前面我们说到,TCP连接其实就是通过三次握手,在通信双方的主机里面保存对应的通信信息,即⽤于保证可靠性和流量控制而维护的某些状态信息称为连接也可以理解成“通信线路”;这些状态信息包括Socket、序列号和窗⼝⼤⼩等。如下图所示:
- 套接字:由 IP 地址、端⼝号以及传输层协议(TCP或UDP)组成
- 序列号:⽤来解决乱序问题等
- 窗⼝⼤⼩:⽤来做流量控制
所以理论上,如果通信双方的“连接信息”不变,一直保存在双方主机,则理论连接会被长期保存。
但是现实却往往是很残酷的,连接经常或被动断开,比如断电(TCP连接信息缓存丢失,导致连接遭到损坏);或一方主机根据情况主动断开,比如不想浪费资源(内存和断开是有限的),一方主机在发送完资源后,用程序主动关闭连接。
二、那么下面就让我们一起来梳理哪些情况会发生连接断开
- 通信双方信息交互完后,一方主动调用TCP软件的“连接断开方法”进行TCP四次挥手断开连接
- 程序奔溃、使用CTRL + C、kill -9 方法杀死进程
- 硬件奔溃:主机损坏、断网等
- 一方断电或宕机
- 防火墙关闭连接
- 其他情况
三、会正常执行TCP四次挥手断开连接的情况有下面几种
1.通信双方信息交互完后,一方主动调用TCP软件的“连接断开方法”
比如,应用程序使用HTTP协议进行信息交互,当交互完后,客户端因为信息发送完成,主动调用close方法或实现http的程序包因为检测到通信双方长时间没有信息交互而主动发起连接断开,这些都发生在应用层,就是程序员开发的应用程序。
2.程序奔溃、使用CTRL + C、kill -9 方法杀死进程
因为应用程序没有主动调用TCP软件的断开流程,将有OS系统自动触发TCP四次挥手断开流程。
3.防火墙关闭连接
防火墙触发TCP四次挥手断开流程。
四、TCP正常断开的四次挥手流程
1. 客户端打算关闭连接,此时会发送⼀个 TCP ⾸部 FIN 标志位被置为 1 的报⽂,也即 FIN 报⽂,之后客户端进⼊ FIN_WAIT_1 状态。
2. 服务端收到该报⽂后,就向客户端发送 ACK 应答报⽂,接着服务端进⼊ CLOSED_WAIT 状态。
3. 客户端收到服务端的 ACK 应答报⽂后,之后进⼊ FIN_WAIT_2 状态。
4. 等待服务端处理完数据后,也向客户端发送 FIN 报⽂,之后服务端进⼊ LAST_ACK 状态。
5. 客户端收到服务端的 FIN 报⽂后,回⼀个 ACK 应答报⽂,之后进⼊ TIME_WAIT 状态,之后的2MSL时间内都是time_wait状态。
6. 服务器收到了 ACK 应答报⽂后,就进⼊了 CLOSED 状态,⾄此服务端已经完成连接的关闭。
7. 客户端在经过 2MSL ⼀段时间后,⾃动进⼊ CLOSED 状态,⾄此客户端也完成连接的关闭。
你可以看到,每个⽅向都需要⼀个 FIN 和⼀个 ACK,因此通常被称为四次挥⼿。
而在日常的tcp连接断开中,一般只有三次挥手,这是因为如果第二次与第三次挥手之间没有数据发送,那么被动断开连接的一方就可能会把第二次的 ACK 与 第三次的 FIN 合并为一次挥手。四次挥手就会变成三次挥手。
五、为何需要四次挥手,而不是像建立连接一样三次挥手?
如果第二次与第三次挥手之间没有数据发送,那么被动断开连接的一方就可能会把第二次的 ACK 与 第三次的 FIN 合并为一次挥手。四次挥手就会变成三次挥手。
- 延时确认,捎带确认
在建立连接的第三次握手的时候,有可能带上数据;在连接断开的四次挥手的第二次挥手,即连接断开被动方在接收到FIN报文的时候,会给断开主动方发送ACK报文,这个报文不会立即发送出去,而是等待200ms(推荐值,但是这个值不能高于500ms),如果在这段时间有用户数据需要发送则一同随着这个ACK发送。
六、为何需要time_wait状态?
主动发起关闭连接的⼀⽅,才会有 TIME-WAIT 状态。TIME _WAIT状态也称为2MSL等待状态。
MSL(Maximum Segment Lifetime)是最大报文段生存时间,它是任何报文段被丢弃前在网络内生存的最长时间,RFC1122建议是2分钟,但BSD传统实现采用了30秒。
当连接转移到TIME_WAIT状态时,即连接主动关闭时,定时器启动,为两倍的MSL。定时器超时,这时才能重新使用之前连接使用的插口(源IP、端口和目的IP和端口的组合即插口也叫四元组)。这也是为了避免一些意想不到的边界情况。
1. time_wait帮助连接正确关闭
断开连接的被动端要确保fin报文正确到达主动端,需要主动端回复ack报文通知被动端fin报文已经成功到达,否则被动端会继续发送fin报文,如果没有time_wait,主动端接收到fin报文回复ack报文,然后进入closed状态,如果ack报文丢失,被动端超时重发fin报文,得到的将是RST报文,这不符合正确关闭的目标。
注:rst 报文在客户端会显示报错信息Connection closed by foreign host。
2. time_wait防止两端在就连接未关闭完全期间在同一个插口建立新连接,导致新旧数据错乱
如果没有time_wait,主动端的ack丢失,同时被动端再次发送fin报文,此时主动端在该插口的状态为关闭,建立新的连接,可能会导致迟到的fin报文使新连接困惑进而导致异常。
七、为何是等待2MSL?
因为断开发起方(主动端)回复ack报文在网络上的过期时间是一个MSL,被动端在 1MSL 内没有收到主动端发出的 ACK 确认报文,就会再次向主动端发出 FIN 报文,被动端重发fin报文在网络上的过期时间也是一个MSL,如果2MSL时间内没有再次收到被动端发送来的fin报文,则主动端认为被动端已经接收到ack报文,关闭了连接,则主动端也关闭连接。
在2MSL时间段内,如果断开主动方(主动端)再次接收到被动端的fin报文,说明服务器端由于各种原因没有接收到客户端发出的 ACK 确认报文。客户端再次向服务器端发出 ACK 确认报文,计时器重置,重新开始 2MSL 的计时。直到2MSL时间内未收到fin报文,正确关闭连接。
假设,被动端的fin报文始终没有收到ack,而2MSL内主动端也没收到fin报文,则被动端在重试了一定次数后也会断掉连接,如果在重试过程中,fin报文又到达主动端,而主动端也过了2MSL,则此时被动端将收到RST报文,使被动端的连接关闭。
TCP定义:
- 在2MSL时间内,连接上的插口不能再继续建立连接
- 平静时间
对于来自某个插口的较早连接的迟到报文段, 2MSL等待可防止将它解释成使用相同插口
对的新连接的一部分。但这只有在处于 2 M S L等待连接中的主机处于正常工作状态时才有效。
如果使用处于2 M S L等待端口的主机出现故障,它会在 M S L秒内重新启动,并立即使用故
障前仍处于2 M S L的插口对来建立一个新的连接吗?如果是这样,在故障前从这个连接发出而迟到的报文段会被错误地当作属于重启后新连接的报文段。无论如何选择重启后新连接的初
始序号,都会发生这种情况。
为了防止这种情况,RFC 793指出T C P在重启动后的M S L秒内不能建立任何连接。这就称
为平静时间(quiet time)。
只有极少的实现版遵守这一原则,因为大多数主机重启动的时间都比MSL秒要长。
八、定时器
1.建立连接定时器 --- Connection-establishment Timer
如果client在连接server的时候, 在发送SYN的时候, 会启动一个定时器(在 3.10 版本中首次超时时间是 1 s,一些老版本中是 3 s。),如果SYN包丢失了, 那么1秒以后会重新发送SYN包的(当然还会启动一个新的定时器, 设置成2秒超时),当然也不会一直没完没了的发SYN包, 在/proc/sys/net/ipv4/tcp_syn_retries 可以设置到底要重新发送几次SYN包。
2. 重传定时器---Retransmission Timer
对于TCP发送出去的数据包, 需要等待对端发来ACK才能从内存里面删除, 那么如果对端没有发送ACK怎么办? 重传。
在发送数据的同时,再设置一个超时时间RTO,如果在这个超时时间内, 没有收到ACK,那么就重传刚才发送的数据。
3. FIN_WAIT_2定时器
在主动关闭的一端调用完close以后(发FIN包给对端, 并且收到对端对FIN的ACK)则进入到FIN_WAIT_2状态, 那么这个时候如果和对端之间的网络坏了或者对端程序有问题了一直不close, 或者对端机器直接掉电了, 本端不能一直傻等, 所以就需要这个定时器.
如果在这个定时器超时的时候,还是没收到对端的FIN包, 那么不好意思, 不等了, 直接释放这个链接。
这个定时器的时间是多少呢?可以从/proc/sys/net/ipv4/tcp_fin_timeout里面看到。
4. 2MSL定时器
在2MSL时间段内,如果断开主动方(主动端)再次接收到被动端的fin报文,说明服务器端由于各种原因没有接收到客户端发出的 ACK 确认报文。客户端再次向服务器端发出 ACK 确认报文,计时器重置,重新开始 2MSL 的计时。直到2MSL时间内未收到fin报文,正确关闭连接。
5. 坚持定时器---Persist Timer
如果某一时刻,一方发现自己的 socket read buffer 满了,无法接受更多的TCP data,此时就是在接下来的发送包中指定通告窗口的大小为0,这样对方就不能接着发送TCP data了。如果socket read buffer有了空间,可以重设通告窗口的大小在接下来的 TCP segment 中告知对方。可是万一这个 TCP segment 不附带任何data,所以即使这个segment丢失也不会知晓(ACKs are not acknowledged, only data is acknowledged)。对方没有接受到,便不知通告窗口的大小发生了变化,也不会发送TCP data。这样双方便会一直僵持下去。
TCP协议采用这个机制避免这种问题:TCP使用了零窗口探测技术(Zero Window Probe,缩写为ZWP),也就是说,接收端在接收窗口变为0后会通知发送端,发送端发现接收端窗口大小变为0,会启动一个定时器,这个定时器就是Persist Timer,在定时器超时后,会发探测报文给接收方,让接收方来ack他的Window尺寸,一般这个值会设置成3次,每次大约30-60秒(不同的实现可能会不一样)。如果3次过后还是0的话,有的TCP实现就会发RST把链接断了。
6. 保活计时器---Keepalive Timer
如果客户端和服务端长时间没有数据交互,那么需要保活定时器来判断是否对端还活着,但是这个其实很不实用,因为默认是2小时没有数据交互才探测,时间实在是太长了。
具体实现方法:TCP每隔一段时间(tcp_keepalive_intvl)会发送一个特殊的 Probe Segment,强制对方回应,如果没有在指定的时间内回应,便会重传,一直到重传次数达到 tcp_keepalive_probes 便认为对方已经crash了。
# TCP KeepAlive 机制,保活时间、保活时间间隔和保活探测次数
net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_intvl
net.ipv4.tcp_keepalve_probes
在 Linux 上可以通过如下文件查看
cat /proc/sys/net/ipv4/tcp_keepalive_time
cat /proc/sys/net/ipv4/tcp_keepalive_intvl
cat /proc/sys/net/ipv4/tcp_keepalive_probes
默认设置是 7200 秒(2 小时)、75 秒和 9 次探测。
如果使用 TCP 自身的 keep-Alive 机制,在 Linux 系统中,最少需要经过 2 小时 11 分 15 秒才可以发现一个“死亡”连接。
这个时间是怎么计算出来的呢?
其实是通过 2 小时,加上 75 秒乘以 9 的总和。
如果你真的要确认对端是否活着, 那么应该在应用层自己实现心跳包,而不是依赖于这个保活定时器。
实际上,对很多对时延要求敏感的系统中,这个时间间隔是不可接受的。
如果开启了 TCP 保活,需要考虑以下⼏种情况:
第⼀种,对端程序是正常⼯作的。当 TCP 保活的探测报⽂发送给对端, 对端会正常响应,这样 TCP 保活时间会被重置,等待下⼀个 TCP 保活时间的到来。
第⼆种,对端程序崩溃并重启。当 TCP 保活的探测报⽂发送给对端后,对端是可以响应的,但由于没有该连接的有效信息,会产⽣⼀个 RST 报⽂,这样很快就会发现 TCP 连接已经被᯿置。
第三种,是对端程序崩溃,或对端由于其他原因导致报⽂不可达。当 TCP 保活的探测报⽂发送给对端后,⽯沉⼤海,没有响应,连续⼏次,达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡。
7. 延迟应答定时器 --- delayed ACK timer
顾名思义, 这个定时器是在延迟应答的时候使用的。
为什么要延迟应答呢?
比如客户端发一段数据给服务端, 服务端本应该立刻回ACK给客户端的, 延迟应答是为了提高网络传输的效率, 比如服务端收到客户端的数据后, 不是立刻回ACK给客户端, 而是等一段时间(一般最大200ms),这样如果服务端要是有数据需要发给客户端,那么这个ACK就和服务端的数据一起发给客户端了, 这样比立即回给客户端一个ACK节省了一个数据包。
参考:
【tcp】TCP协议中的7种定时器 - 简书
TCP协议的超时详解 - 简书
九、非四次挥手连接损坏
1)硬件奔溃:主机损坏、断网等
2)一方断电或宕机
1. 没有数据传输的时候主机奔溃
如果对方在开启了TCP keepalive 保活,那么如果在机器停机期间,如果对方发送了保活探测报文,此时未奔溃端的探测报文会石沉大海,不会被响应,连续几次后,达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡。
# TCP KeepAlive 机制,保活时间、保活时间间隔和保活探测次数
net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_intvl
net.ipv4.tcp_keepalve_probes
在 Linux 上可以通过如下文件查看
cat /proc/sys/net/ipv4/tcp_keepalive_time
cat /proc/sys/net/ipv4/tcp_keepalive_intvl
cat /proc/sys/net/ipv4/tcp_keepalive_probes
2. 有数据传输的时候主机奔溃
数据会超时重传,数据报文的重传次数达到一定阈值后,内核就会判定出该 TCP 有问题,然后通过 Socket 接口告诉应用程序该 TCP 连接出问题了,一般就是 ETIMEOUT 错误状态码。
那具体重传几次呢?
在 Linux 系统中,提供一个叫 tcp_retries2 配置项,默认值是 15,可以通过
Cat /proc/sys/net/ipv4/tcp_retries2 查看和设置。
这个内核参数是控制,在 TCP 连接建立的情况下,超时重传的最大次数。
不过 tcp_retries2 设置了 15 次,并不代表 TCP 超时重传了 15 次才会通知应用程序终止该 TCP 连接,内核还会基于「最大超时时间」来判定。
超时重传阶段每一轮的超时时间都是倍数增长的,比如第一次触发超时重传是在 2s 后,第二次则是在 4s 后,第三次则是 8s 后,以此类推。
但是这个超时时间不会无限增加下去,会受到最大超时时间的限制,超时时间的计算根据一下公式来计算:
其中rto_base为200ms;TCP_RTO_MAX为120000ms。
机器恢复后,因为异常导致本方TCP连接信息丢失,重启完成后,收到之前 TCP 连接的报文,都会回复 RST 报文,以断开连接。
十、解决连接断开过程中的问题
1. time_wait 堆积过多如何解决
危害:
① 内存资源的占用
② 对端口资源的占用,一个 TCP 连接至少消耗「发起连接方」的一个本地端口
要直到端口资源是有限的(只有65536),如果被time_wait占用过多,占满了所有端口资源,则会导致无法创建新连接,影响正常的使用。
原因:
可能是高并发情况下,高并发让服务器在短时间范围内同时占用大量端口,而业务处理+传输数据的时间 远远小于 TIME_WAIT的2MSL超时时间,导致很多time_wait对接,影响其他正常的连接。
解决:
① 修改内核参数---设置time_wait的连接重用或快速回收
- net.ipv4.tcp_tw_reuse = 1
表示开启重用。允许将time_wait sockets重新用于新的TCP连接,默认为0,表示关闭;
因为重用插口,新连接不能处理旧数据,TCP需要能判断到达的数据是否为旧数据,实现原理是根据时间戳判断是否是延迟的数据,如果是,则丢弃。要实现这个功能就需要开启TCP对时间戳的支持,这个内核参数是:net.ipv4.tcp_timestamps=1(默认即为 1,开启);这个时间戳的字段是在 TCP 头部的「选项」⾥,⽤于记录 TCP 发送⽅的当前时间戳和从对端接收到的最新时间戳。
由于引⼊了时间戳,我们在前⾯提到的 2MSL 问题就不复存在了,因为重复的数据包会因为时间戳过期被⾃然丢弃,不会对新旧数据产生混淆。
- net.ipv4.tcp_tw_recycle = 1
表示开启TCP连接中time_wait sockets的快速回收,默认为0,表示关闭。
- net.ipv4.tcp_max_tw_buckets
这个值默认为 18000,当系统中处于 TIME_WAIT 的连接⼀旦超过这个值时,系统就会将后⾯的 TIME_WAIT 连接状态重置。
这个⽅法过于暴⼒,⽽且治标不治本,带来的问题远⽐解决的问题多,不推荐使⽤。
② 客户端:短链接改长连接
HTTP 请求的头部, connection 设置为 keep-alive, 保持存活一段时间;
长连接从根本上减少了关闭连接的次数,减少了TIME_WAIT状态的产生数量,在高并发的系统中非常有效,现在的浏览器, 一般都这么进行了 。
③ 缩减 time_wait 时间
例如: 设置为 1 MSL(即, 2 mins)
④ 不主动关闭连接
不主动关闭socket,就不会产生TIME_WAIT状态
⑤ 程序中使⽤ SO_LINGER
我们可以通过设置 socket 选项,来设置调⽤ close 关闭连接⾏为。
struct linger so_linger;
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
setsockopt(s, SOL_SOCKET, SO_LINGER, &so_linger,sizeof(so_linger));
如果 l_onoff 为⾮ 0, 且 l_linger 值为 0,那么调⽤ close 后,会⽴该发送⼀个 RST 标志给对端,该 TCP 连接将跳过四次挥⼿,也就跳过了 TIME_WAIT 状态,直接关闭。
但这为跨越 TIME_WAIT 状态提供了⼀个可能,不过是⼀个⾮常危险的⾏为,不值得提倡。
参考:
服务器出现大量TIME_WAIT状态怎么解决_最大进程打开文件timewait-CSDN博客
2. close_wait 堆积过多如何解决
危害:
使服务端的服务不可用。
原因:
被服务端没有发送fin报文导致,没有发送的原因一般都是程序因为被阻塞(比如调用远程资源)或者异常代码死循环,让客户端超时关闭,客户端发送关闭请求,服务端回复ack,但是由于各种原因导致服务端程序一直在运行阻塞无法发出fin报文。
解决:
① 修改内核参数
开启TCP保活检测
② 资源的访问一定要设置访问超时时间
比如数据库访问超时,第三方资源访问超时等。
③ 代码要规范,资源要牢记释放
相关文章:
第三十篇:TCP连接断开过程,从底层说明白,TCP系列五
上一篇《第二十九篇:图解TCP三次握手,看过不会忘,从底层说清楚,TCP系列四》说了TCP的三次握手,接下来我将讲解TCP四次挥手。 既然有连接就有断开,谈到这里,有的同学可能会想,不就是…...
代码随想录算法训练营第七天| 哈希表理论基础 454.四数相加II 383.赎金信 15.三数之和 18.四数之和
454. 四数相加 II 题目 给定四个包含整数的数组 A, B, C, D,计算有多少个元组 (i, j, k, l) 使得 A[i] B[j] C[k] D[l] 0。 解题思路 先计算数组 A 和 B 的所有组合和,并存入哈希表 map 中,键为组合和,值为该和出现的次数…...
搜维尔科技:Manus新品发布Metagloves Pro专业版,专为高精度需求的客户打造,尤其是人形机器人产业与人机工效研究使用
manus新品发布Metagloves Pro专业版,专为高精度需求的客户打造,尤其是人形机器人产业与人机工效研究使用 搜维尔科技:manus新品发布Metagloves Pro专业版,专为高精度需求的客户打造,尤其是人形机器人产业与人机工效研究…...
Spring Boot实现的动态化酒店住宿管理系统
1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理酒店客房管理系统的相关信息成为必然。开发…...
数字IC后端实现Innovus |给各种IP子模块添加port buffer和antenna diode万能脚本
我们之前分享过在hierarchical flow后端实现中为了确保顶层flatten时timing signoff和physical signoff看到的情况和模块级看到的情况一致,我们会在模块io port添加io port buffer(主要是timing,antenna一致性)。实际上在芯片级我…...
反向代理服务器---NGINX
1.NGINX NGINX(发音为“engine-x”)是一个开源的高性能HTTP服务器和反向代理服务器。它被广泛用于互联网应用程序的加速、负载均衡和高可用性的配置。NGINX具有低内存消耗、高并发能力和卓越的性能,能够处理大量并发连接和高流量的网络流量。…...
unity3d————场景管理类SceneManager
常用API SceneManager.LoadScene(string sceneName) 加载名为 sceneName 的场景。SceneManager.LoadScene(int sceneBuildIndex) 根据场景在Build设置中的索引加载场景。SceneManager.GetActiveScene() 获取当前活动的场景。SceneManager.GetSceneByName(string name) 根据名称…...
鹅厂面试官:Transformer 为何需要位置编码?
最近这一两周看到不少互联网公司都已经开始秋招发放Offer。 不同以往的是,当前职场环境已不再是那个双向奔赴时代了。求职者在变多,HC 在变少,岗位要求还更高了。 最近,我们又陆续整理了很多大厂的面试题,帮助一些球…...
MySQL数据库学习指南
一、数据库的库操作 1、创建数据库 2、删除数据库 3、查看数据库 4、选择数据库 5、修改数据库 6、数据库备份与恢复 7、数据库的权限管理 二、数据库的表操作 1、创建表 2、删除表 3、修改表 4、查看表的结构 5、查看表的数据 6、创建索引 7、删除索引 8、约束…...
算法刷题-小猫爬山
本题来源165. 小猫爬山 - AcWing题库 翰翰和达达饲养了 NN 只小猫,这天,小猫们要去爬山。 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<)。 翰翰和达达只好花…...
Maven项目管理工具-初始+环境配置
1. Maven的概念 1.1. 什么是Maven Maven是跨平台的项目管理工具。主要服务于基于Java平台的项目构建,依赖管理和项目信息管理。 理想的项目构建:高度自动化,跨平台,可重用的组件,标准化的流程 maven能够自动下载依…...
【JavaEE初阶】网络编程TCP协议实现回显服务器以及如何处理多个客户端的响应
前言 🌟🌟本期讲解关于TCP/UDP协议的原理理解~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么废话不多说…...
Android 中的串口开发
一:背景 本文着重讲安卓下的串口。 由于开源的Android在各种智能设备上的使用越来越多,如车载系统等。在我们的认识中,Android OS的物理接口一般只有usb host接口和耳机接口,但其实安卓支持各种各样的工业接口,如HDM…...
TensorRt OP
在TensorRT中,OP(Operations,操作)是指网络中的基本计算单元,类似于数学中的运算符。每个OP执行一个特定的计算任务,例如卷积、矩阵乘法、激活函数等。TensorRT通过识别和优化这些OP来提高深度学习模型的推…...
构建负责任的人工智能:数据伦理与隐私保护
构建负责任的人工智能:数据伦理与隐私保护 目录 🌟 数据伦理的重要性📊 公平性评估:实现无偏差的模型🔒 数据去标识化:保护用户隐私的必要手段🔍 透明性与问责:建立可信的数据处理…...
微信小程序live-pusher和video同时使用,video播放声音时时大时小
一、遇到的问题 微信小程序live-pusher和video同时使用,video播放声音时有时无时大时小 二、排查流程 业务是模拟面试,每道题一个推流live-pusher和一个面试题video,一次面试有多道面试题,页面就一个live-pusher和一个video,切换面试题时给live-pusher和video重新赋值u…...
MySQL 分库分表实战
在当今互联网时代,数据量的增长呈爆炸式趋势,传统的单库单表架构已经难以满足大规模数据存储和高并发访问的需求。MySQL 分库分表技术应运而生,它可以有效地提高数据库的性能、扩展性和可用性。本文将详细介绍 MySQL 分库分表的实战经验。 一…...
MySQL—CRUD—进阶—(二) (ಥ_ಥ)
文本目录: ❄️一、新增: ❄️二、查询: 1、聚合查询: 1)、聚合函数: 2)、GROUP BY子句: 3)、HAVING 子句: 2、联合查询: 1)、内连接…...
时序分解 | TTNRBO-VMD改进牛顿-拉夫逊算法优化变分模态分解
时序分解 | TTNRBO-VMD改进牛顿-拉夫逊算法优化变分模态分解 目录 时序分解 | TTNRBO-VMD改进牛顿-拉夫逊算法优化变分模态分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 (创新独家)TTNRBO-VMD改进牛顿-拉夫逊优化算优化变分模态分解TTNRBO–VMD 优化VMD分解层数K和…...
2024“源鲁杯“高校网络安全技能大赛-Misc-WP
Round 1 hide_png 题目给了一张图片,flag就在图片上,不过不太明显,写个python脚本处理一下 from PIL import Image # 打开图像并转换为RGB模式 img Image.open("./attachments.png").convert("RGB") # 获取图像…...
CSS行块标签的显示方式
块级元素 标签:h1-h6,p,div,ul,ol,li,dd,dt 特点: (1)如果块级元素不设置默认宽度,那么该元素的宽度等于其父元素的宽度。 (2)所有的块级元素独占一行显示. (3ÿ…...
Go 语言中的 for range 循环教程
在 Go 语言中,for range 循环是一个方便的语法结构,用于遍历数组、切片、映射和字符串。本教程将通过示例代码来帮助理解如何在 Go 中使用 for range 循环。 package mainimport "fmt"func main() {// 遍历切片并计算和nums : []int{2, 3, 4}…...
青训营 X 豆包MarsCode 技术训练营--小M的比赛胜场计算
问题描述 小M参加了一场n个人的比赛,比赛规则是所有选手两两对决。每个人有一个能力值,对应着他们的序号。参赛者同时被分为黄色或蓝色两种颜色。比赛胜负的规则如下: 当比赛双方颜色不同时,能力值大的选手获胜; 当比…...
海王3纯源码
海王3是一款热门的捕鱼类游戏,其纯源码为开发者提供了一个完整的游戏开发基础。该源码包括客户端和服务端的完整架构,支持多人在线竞技模式和丰富的游戏玩法。服务端采用C语言编写,并使用MySQL数据库来存储玩家数据,确保数据处理的…...
【ShuQiHere】Linux 系统中的硬盘管理详解:命令与技巧
【ShuQiHere】 💽 在 Linux 系统中,硬盘管理不仅仅是存储数据的操作,更涉及系统性能、数据安全和稳定性的优化。无论你是系统管理员、开发者还是 Linux 爱好者,掌握硬盘管理的基础操作都非常有用。本文将从硬盘健康检查、分区管理…...
数据结构之堆和二叉树的简介
1.树 1.1 树的概念与结构 如图所示,树是⼀种非线性的数据结构,它是由 n (n>0) 个有限结点组成⼀个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 …...
微信小程序上传图片添加水印
微信小程序使用wx.chooseMedia拍摄或从手机相册中选择图片并添加水印, 代码如下: // WXML代码:<canvas canvas-id"watermarkCanvas" style"width: {{canvasWidth}}px; height: {{canvasHeight}}px;"></canvas&…...
xshell5找不到匹配的host key算法
xshell5找不到匹配的host key算法,是因为电脑客户端不支持服务器的算法,因此需要再服务器增加算法。 下面以Ubuntu系统为例,修改下面的文件 sudo vim /etc/ssh/sshd_config 增加下面算法 KexAlgorithms diffie-hellman-group-exchange-…...
Linux中安装Tomcat
文章目录 一、Tomcat介绍1.1、Tomcat是什么1.2、Tomcat的工作原理1.3、Tomcat适用的场景1.4、Tomcat与Nginx、Apache比较1.4.1、优势1.4.2、劣势1.4.3、定位功能 1.5、Tomcat 的主要组件1.6、Tomcat 的主要配置文件 二、Tomcat安装2.1、查看可用的JDK2.2、安装OpenJDK 112.3、配…...
RV1126音视频学习(二)-----VI模块
文章目录 前言2.RV1126的视频输入vi模块2.1什么是VI模块2.3RV1126VI模块主要APIRK_MPI_SYS_Init()RK_MPI_VI_SetChnAttrRK_MPI_VI_EnableChnRK_S32 RK_MPI_VI_DisableChnRK_MPI_VI_StartStreamRK_MPI_SYS_GetMediaBufferRK_MPI_MB_GetPtrRK_MPI_MB_GetSizeRK_MPI_MB_ReleaseBuf…...
灵犀科技网站建设/外链工具
1. 加载数据库驱动 通常来说,JDBC 使用 Class 类的 forName() 静态方法来加载驱动,需要输入数据库驱动代表的字符串。 例如: 加载 MySQL 驱动: Class.forName("com.mysql.jdbc.Driver"); 加载 Oracle 驱动: …...
找人做彩票网站多少钱/my63777免费域名查询
我创建了一个Win32服务器 - 客户端应用程序,其中许多客户端连接到单个服务器,发送查询和 recv 响应 .它在许多安装中都能正常工作,但在其他一些安装中关闭了连接 . 客户端和服务器都报告远程主机已关闭连接 . 创建连接后的套接字操作顺序如下…...
网站建设需/网络营销的四大要素
一、功能实现核心:FileSystemObject 对象 其实,要在Javascript中实现文件操作功能,主要就是依靠FileSystemobject对象。在详细介绍FileSystemobject对象的各个属性和方法的使用细节前,先来看看这个对象包括哪些相关对象和集合&…...
沈阳做网站客户多吗/济南网络seo公司
在开发团队,会出现vs工具使用版本的不一样的情况。我的电脑使用的是VS2010,可是其他人员使用的是vs2013. 要打开其他人员上传的工程文件,可以通过三种方式: 1、下载一个vs2013版本. 2、使用vs2012新建一个空的项目,把其…...
阿里云备案网站备案域名购买/百度推广账号登录入口
本文力图解析以下几个问题什么是装饰器装饰器的原理装饰器与闭包的关系装饰器的执行顺序什么是装饰器装饰器模式是一种允许动态或者静态向一个对象添加新的行为而不会影响到其他对象的一种设计模式。Python提供了一种更为自然的方式来装饰一个函数,这种方法通过在被…...
外贸营销单页网站/杭州网站建设公司
题目:通信网络及技术与我 字数:千字左右 主要内容围绕两个方面:1自己生活环境的通信方式,涉及的通信技术,本地运营商选择及优劣 2通信对未来职业规划的影响及选择 ---------------------------------------------------------------------------------…...