udp tcp协议
文章目录
- 1. UDP协议
- 1.1 端口号
- 1.2 UDP协议格式
- 1.3 UDP特性
- 1.4 报文的封装
- 2. TCP协议
- 2.1 TCP协议格式
- 2.2 TCP策略
- 2.2.1 确认应答机制(ACK)
- 序号与确认序号
- 6个标志位
- 序号的理解
- 2.2.2 超时重传机制
- 2.2.3 连接管理机制
- 三次握手
- 四次挥手
- 理解三次握手
- 理解四次挥手
- 2.2.4 流量控制
- 2.2.5 滑动窗口
- 2.2.6 拥塞控制
- 2.2.7 延迟、捎带应答
- 2.3 面向字节流
- 2.4 粘包问题
- 3. TCP全连接队列
- 3.1 backlog
- 3.2 全连接队列的原理
- 4. `tcpdump`
1. UDP协议
1.1 端口号
在前面的文章中说过,每一个要网络通信的进程,都要绑定IP地址和端口号
其中端口号划分为两部分:
- 0~1023:一些知名协议已经绑定了的端口号
- 1024~65535:OS随机分配的端口号
在OS内部,端口号与进程之间的关系类似于哈希表,通过键值port能找到唯一的进程与之对应
同时,也能说明,一个进程能够绑定多个端口号,但一个端口号只能被一个进程绑定
1.2 UDP协议格式
-
如何将报头与有效载荷分离?
UDP报头字段固定8字节,读取其中的16位UD长度,减去8字节就是有效载荷的长度
-
如何分用?
根据报头中的16位目的端口号将有效载荷向上层交付
1.3 UDP特性
- 无连接
- 不可靠
- 面向数据报
无连接,在socket编程章节中已有所体现,使用udp
通信的双方创建好套接字就能直接通信
而对于不可靠这一特性,讲完tcp
的可靠性,自然也就懂了
所谓面向数据报,发送方发多少,接收方就接多少,不能灵活控制发送和接受的次数
udp
注意事项:udp
没有发送缓冲区,调用sendto
直接由内核发送,但有接受缓冲区;udp
报头字段中的16位长度表明udp
最大长度是64KB,如果发送的数据超过64KB,则需要分批发送
1.4 报文的封装
所谓的报头,在内核中其实就是结构体字段
在应用层,由于双方操作系统、机器大小端、计算机语言等的不同,发送的数据需要先进行序列化
而传输层属于内核,内核的部分双方几乎一样,都是用C写的,进行序列化再传输反而增加了传输量
因此,横向来看,udp
报头是以结构体直接发送的
纵向来看,在OS中,可能同时存在各种各样的报文,有准备向上交付的,有准备向下交付的,有要丢弃的…那么OS就需要对这些报文进行管理 ----- 先描述,再组织;所以,报文的本质也是一个内核数据结构,它有非常多的属性,其中我们重点了解两个指针
当应用层向下交付时,数据存放在内核中的一段内存上,该内存前面预留了一些空间
最开始,sk_buff
中的head
和data
都指向数据的起始位置
当要封装udp
报头时,head
向前移动udp
报文长度个字节,并赋好值,这样就完成了报文的封装,往下依旧如此
2. TCP协议
2.1 TCP协议格式
-
如何将有效载荷与报头分离?
tcp
协议格式中的4位首部长度,每bit位表示4字节,总共能表示[0, 60]字节tcp
协议格式前20字节固定,取出后,拿4位首部长度 - 20字节就是选项,剩余的就是数据 -
如何分用?
接收方根据16位目的端口号向上交付
2.2 TCP策略
我们知道,tcp
协议是可靠的、面向连接的,那么tcp
是如何保证可靠性,如何连接的呢?这与tcp
策略息息相关
2.2.1 确认应答机制(ACK)
发送方发送的报文,可能在传输的过程中丢了,也可能对方收到了,那发送方如何得知报文究竟是丢了还是对方收到了?
很简单,如果对方收到报文,只要给我个应答,就证明我之前发送的数据对方一定收到了;相反,如果我没收到应答,则证明我发送的报文对方没收到
但是又有问题了,S怎么得知应答对方一定收到了呢?在这里,我们规定,不对应答进行应答,因为如果对应答进行应答,就会无限套下去,C又怎么得知自己的应答对方一定收到…
因此,对于应答,我们无法保证可靠性,但只要收到应答,历史发送的数据对方一定收到;而如果没收到应答,不管是报文丢失,还是应答丢失,发送方就认为对方没收到报文
所谓可靠性,指的是对方收到报文了,我能知道,对方没收到报文,我也能知道
我们把这种确认应答机制也叫做ACK机制,当进行应答时,需要将tcp
报头字段中的ACK
标志位置1,双方都采用ACK机制,就能保证数据传输的可靠性
序号与确认序号
tcp
有两种通信模式,一种是向上述那样,发送一个报文,回一个应答
但更常用的则是:发送方可以一次发送多个报文,接收方在接收到报文后分别对每个报文进行应答,从而提高通信效率
那么接收方对每个报文应答后,发送方如何确认哪个应答对于哪个报文呢?这就需要tcp
报头中的序号与确认序号
当发送方发送报文时,需要对该报文填写唯一性标识 ---- 序号,当接受方收到报文进行应答时,填写确认序号,其中确认序号 = 序号 + 1
其中确认序号的含义是:+1之前的数据已经全部收到,下次从+1的数据开始发
比如当发送方发送序号为2000的报文,接收方应答时确认序号填写2001,如果接收方收到应答,则认为2000之前的数据对方已经全部收到,下次从2001开始发
同时,如果应答部分丢失,只要收到最近一次报文的应答,就认为之前的报文对方一定收到,因此,该做法允许部分应答丢失
从上述例子看,貌似tcp
只需要一个序号也能对每个发送的报文进行确认,当发送时,填写序号,应答时,将序号当作确认序号来填,不也ok吗?为什么要以序号 + 确认序号的方式?
当发送方发送报文时,对方进行应答的同时,也想发送数据,此时为了提高通信效率,接收方将ACK
与要发送的数据作为一个报文,将ACK
标志位置1 + 填写确认序号表示应答,填写序号 + 数据表示要发送的数据;在这种情况,就需要序号 + 确认序号
6个标志位
在udp
协议中我们说过,OS内有各种各样的报文,在tcp
这里更是如此,有应答报文、还有后面讲的发起连接的报文、断开连接的报文等等
因此,OS要对它们进行管理的同时,还要能够对它们进行区分,如何区分报文?根据tcp
报头中的6个标志位
序号的理解
根据我们学过的知识,应用层调用sendto
,本质是将数据拷贝到发送缓冲区,在这里,我们不妨将缓冲区看作字符数组,于是每一字节就天然的有一下标,序号的本质就是发送缓冲区数组的下标
当确认序号为1001时,表示1000之前的数据已经收到,下次从下标为1001的位置开始发
2.2.2 超时重传机制
当发送方发送报文,在一段时间以内,没有收到应答,此时就认为报文丢失,会重新发送报文,我们把这种机制叫做超时重传机制
那么超时时间应该是多少呢?由于报文是经过网络传输的,而网络的状态是浮动的,有时好,有时坏,当网络好时,超时时间应该短点,以提高效率,但网络坏时,超时时间应该长些,因此,超时时间也应当是浮动
一般来说,linux
下的超时时间起初是500ms,第二次发送没收到应答时,超时时间变为2 * 500ms,以此类推,如果连续多次超时重传后还是无法收到应答,则关闭连接
没有收到应答的原因可能是报文丢失,也可能是应答丢失,如果是应答丢失,表明对方收到报文,如果重新发送报文,且对方收到,此时对方的OS内就有两份相同的报文;OS会根据序号来判断两份报文是否相同,如果相同,则丢弃新报文的并给出应答
tcp
通信模式中,常见的是第二种,多个报文一并发送时,由于报文是经过网络传输的,它们走的线路不同,到达对方主机的时间也就不同,也就意味着发送的报文可能是有序的,但接受时可能是无序的,此时,OS会根据报文的序号来排序,确保向上层交付的数据是有序的
总上来看,序号的作用主要有3点:
- 对发送的报文进行唯一性确认
- 对报文进行去重
- 使报文按序到达
2.2.3 连接管理机制
三次握手
我们总是tcp
是面向连接的,那么它是如何建立连接的?
使用tcp
协议通信的双方,在通信之前需要建立连接,通常由client发起连接
当server调用listen
后,进入LISTEN
状态,client调用connect
,发起连接,连接报文中不能携带数据,将SYN
标志位置1,表示是连接报文,询问sever,我要和你建立连接,你是否同意
server收到报文后,同意建立连接的同时,反问client,我同意你到我的一个连接,但我也要和你建立连接,你是否同意
client收到报文后,同意server到client的连接
在上述过程中,client发起SYN,收到SYN + ACK,发送ACK,总共收发3个报文;server收SYN,发SYN + ACK,收ACK,也总共收发3个报文
我们把上述建立连接的过程叫做tcp
的三次握手
那么问题来了,如果client发出的最后一个ACK丢失了呢,由于无法保证应答的可靠性,不就代表连接建立失败了吗?事实上,的确如此,所以建立建立的本质就是在赌最后一个ACK对方一定收到
那如果最后一个ACK就是丢了呢?其实也是有办法的,要注意,对于client,在发送最后一个ACK时,它到server的连接已经建立好
但对于server,只有收到ACK时,它到client的连接才建立好
也就是说client->server的连接与server->client的连接建立好之间,有一段时间间隔
在这段间隔之内,也就是server->client的连接建立好之前,client有可能已经给server发送了数据报文,如果最后一个ACK丢了,而server又收到了client发送的数据报文,此时server判断自身连接还没建立,就会给client发送一个将RST
标志位置1的报文,表示异常连接,要求client重新建立连接,client收到后,就会断开连接,重新发起三次握手
不仅仅是上述示例中,在通信的任何时刻,只要发现tcp
连接异常,都可以向对方发送RST
标志位置1的报文,重新建立连接
四次挥手
建立连接后,双方正常通信,突然client不想通信了,关闭了文件描述符,于是发起断开连接的报文 — 将FIN
标志位置1,询问对方,我想和你断开连接,你是否同意,server同意了,给了应答
过会,server也不想和client通信了,于是也关闭文件描述符,发起断开连接的报文,server要client断开连接,问client是否同意,client也同意,至此,双方的连接彻底断开
同理,client和server收发报文各自总共4次,我们也把双方断开连接的过程叫做tcp
四次挥手
在这里,又有几个问题
-
根据上文说的,能不能将server发给client的ACK与server要与client断开连接FIN报文合并?
不能,一方想要与对方断开连接,原因是我要发给对方的数据已经发完了,所以我要和对方断开连接,但对方要给我发送的数据不一定发完
因此,client发送的数据发完,就和对方断开连接,此时server仍可能要给client发送数据,等到server的数据发完,由server自主发起断开连接
这也是为什么断开连接叫四次挥手
-
根据现有的知识,一个
fd
对应一个连接,一个连接在传输层对应两个缓冲区,发送和接受缓冲区,既然client已经关闭fd
了,也就是销毁发送和接受缓冲区了,为什么还能接受server发来的数据?这里的close(),我们可以理解为
shutdown(sockfd, SHUT_WR)
,也就是只关闭了发送缓冲区,等到双方的连接都断开,才是真正的close()
需要注意的是,client应答ACK后,到server收到应答,需要一段时间,这也是为什么之前我们写tcp
服务器时,关闭服务器后又立马重启发现绑定端口号错误的原因,只要没收到应答,连接就还在,端口号就还在被占用,也就绑定失败了
理解三次握手
建立连接,为什么是三次握手?
在OS内,连接有很多种,有正在三次握手的连接、正在四次挥手的连接、正常通信的连接…OS需要对这些连接管理 — 先描述,再组织,连接在OS内本质也是内核数据结构,需要花费空间创建结构体对象,花费时间管理,这意味着管理连接是需要成本的
首先,来看一次和两次为什么不行,一次不用说了,SYN报文的可靠性都不能保证;而两次中,client发送SYN,server收到应答就建立好连接,由于建立连接的成本太低,client可以向server发送大量建立连接的报文,而server对每个连接都默认接受,导致server承受过重压力,可能会引发SYN洪水问题
而三次握手,虽然也可能存在SYN洪水的问题,但最重要的是:
- 验证了双方网络的连通性
- 以最小的成本建立双方通信的共识
client能收、能发,client->server网络正常,server也能收、能发,server->client网络正常,双方网络连通
client想和server通信,server同意了,server也想和client通信,client同意了,双方达成共识
以上两点,一次两次握手都达不到,因此,这才是为什么tcp
建立连接是三次握手的原因
理解四次挥手
实际上,跟三次握手同理,四次挥手之所以叫做四次挥手,在于它以最小的成本建立双方断开连接的共识
根据我们四次挥手图的理解,对方在收到建立连接的报文后,如果不关闭fd
,会处于CLOSE_WAIT
的状态;同时,主动断开连接的一方,在收到对方断开连接的报文后,会处于TIME_WAIT
的状态,下面我们来验证
我们拿tcp_echo_server
来验证
那么主动断开连接的一方为什么最后要处于TIME_WAIT
的状态?
该状态维持多长时间?
能不能不处于该状态,好让下次服务器直接重启?
报文是经过网络传输的,当断开连接时,报文可能还在传输的路上,如果连接直接断开,又立马重启了,这时就可能收到上次在网络中遗留的报文,影响到了本次通信,因此,处于TIME_WAIT
的状态就是为了等待这些报文到达后,将它们丢弃;也有另一个原因,就是最后一个ACK,server不一定收到,超时时间后,server会再次发送FIN,此时client还没退出,就能再ACK,确保server也能退出
处于TIME_WAIT
的状态的时长一般是2 * MST,这里的MST是报文的最大生存时间,根据操作系统而变
cat /proc/sys/net/ipv4/tcp_fin_timeout # 查看当前系统的MST
要想client退出后,不进入TIME_WAIT
状态,将server的listensockfd
设置以下即可
2.2.4 流量控制
应用层调用write,将数据拷贝到发送缓冲区,由tcp
控制数据的传输;如果对方的接受缓冲区满了,那么到达的报文也就直接丢弃了,这种做法虽然可行,但却不合理,报文的传输消耗了网络资源,CPU等硬件资源,却就这样被丢弃
因此,tcp
在传输数据时,应该要考虑对方的接受能力,根据对方接受能力的大小来控制数据应该发多少,我们把这种策略叫做流量控制
所谓对方的接受能力,实际就是对方接受缓冲区剩余空间的大小
那么,发送方该如何得知对方的接受能力呢?
这就引入tcp
报头字段中的"16位窗口大小"了,在对报文应答时,不仅要将ACK标志位置1,有数据的加数据,还要将自身发送缓冲区剩余空间的大小填入16位窗口大小中,这样,对方在收到ACK时,就能得知我当前的接受能力
在tcp
报文字段中的选项中,可能会有窗口扩大因子的选项,实际的窗口大小 = 窗口大小 << 窗口扩大因子
实际上,在tcp
三次握手时,双方就是在告知对方自身最初的接受能力
在极端情况下,对方的接受能力为0,此时发送方停止发送数据,对方也就不ACK了,对方的接受能力也就无从得知了,此时如何判断对方有接受能力了,从而继续发送数据?
一方面,接收方会时不时的发送窗口更新通知的报文,主动告知自身的接受能力;另一方面,发送方也会时不时的发送窗口探测报文,对方只要ACK,就能得知其接受能力
那如果对方的接受能力仍然是0呢?发送方可以发送PSH
标志位置1的报文给对方,提醒对方尽快将缓冲区里的数据向上交付;任何时候,只要希望数据尽快向上交付,都能将PSH
标志位置1
至此,还剩一个URG
标志位,它通常配合16紧急指针使用,为1表示紧急指针有效,否则无效;紧急指针实际是一个偏移量,指向接受缓冲区中某1字节;有时,我们给对方发送数据,在某一时刻希望取消发送数据,于是发送URG
标志位置1的报文,但如果接收方依旧按序接受报文,当读到URG
标志位,前面的报文已经处理完毕,又要撤回,相当于前面的工作白做了;因此,tcp
提供了某些报文"插队"的做法,一般两个进程,一个正常读取,一个快速读取URG
标志位,如果为1,则告知另一个进程取消读取
2.2.5 滑动窗口
前面我们介绍了超时重传机制和流量控制,但仍有问题:
- 已经发送的报文,在接受到ACK之前或者超时重传时间之内,不能被丢弃,需要保存起来,保存在哪?
- 通过窗口大小已经得知对方的接受能力,如何根据对方的接受能力进行数据的发送呢?
为了解决上述问题,tcp
引入滑动窗口的概念,规定,在滑动窗口以内的数据可以直接发送,暂时可以不做应答
所谓的滑动窗口,实际就是发送缓冲区的一段区域,于是,滑动窗口将发送缓冲区分成三部分
到这里,我们可以粗略的将滑动窗口定义为:滑动窗口 = 对方的接受能力(对方接受缓冲区剩余空间的大小)
于是,我们根据滑动窗口的定义,来判断下面的问题:
-
滑动窗口能不能向左移动?
已发送,已应答的数据无需再发送,因此滑动窗口只能向右移动,不能向左
-
滑动窗口能不能变大?变小?为0?
滑动窗口 = 对方的接受能力,对方应用层调用
read
,接受能力就变大了,滑动窗口也就变大了;同理,滑动窗口也能变小,甚至为0
又根据之前的知识,缓冲区可以认为是一个字符数组,我们进一步将滑动窗口精细化的描述
滑动窗口本质是数组中的两个下标
现在,我们已经知道滑动窗口的具体含义了,可以根据滑动窗口来进行数据的发送了
那么问题来了,如果发送的报文丢了呢?
拿上图举例,如果最左边报文丢失,接收方在对其他报文进行应答时,根据确认序号的定义,只能填0,因为1000的报文没收到,当发送方收到3个以上的相同应答,触发快重传机制,立即补发1000的报文,接收方可以直接ACK4001,表示4000之间的报文已经收到
对应滑动窗口,win_start不动
如果是中间报文丢失,接收方ACK确认需要填1001,win_start右移,此时问题变成最左边报文丢失
最右边报文丢失同理,最终变成最左边报文丢失问题
上面提到的快重传机制与超时重传机制有何不同?
快重传是连续收到3个以上同样的应答所触发;如果在通信末期,可能报文丢失,但收不到3个以上的同样的应答,此时超时重传能进行报文的补发;可以说,超时重传是为报文的可靠性兜底的
如果是ACK丢失呢?这点我们之前说过,允许ACK丢失,只要收到最后的ACK,就能保证前面的数据对方收到了
因此,重新看待最开始的两个问题,收到ACK之前,报文保存在哪?---- 滑动窗口中;如何根据对方的接受能力控制数据的发送—滑动窗口内的数据就是能直接发送给对方的数据
2.2.6 拥塞控制
报文是经过网络传输的,网络有时好,有时坏;因此,有时报文的丢失可能是因为网络的原因
如何得知报文的丢失是因为网络的原因还是对方主机的原因呢?
如果发送100报文,其中小部分丢失,则判断网络状况正常,而如果大部分都丢失了,则认为是网络的原因,网络出现了拥塞问题
一旦网络出现拥塞问题,就要降低发送报文的数量,由于所有主机传输数据都遵循tcp
协议,因此当网络出现拥塞,所有主机都能降低报文发送的数量,解决拥塞问题的关键在于,所有主机都有拥塞避免的共识
tcp
引入拥塞窗口,它的含义是导致网络拥塞的最大报文数量
因此,在最开始,我们发送报文的数量不能超过导致网络拥塞的报文数量,滑动窗口 = min(对方的接受能力,拥塞窗口)
由于网络是浮动的,拥塞窗口也应当浮动,如何得知当前网络的拥塞窗口?一定需要多次探测
为什么拥塞窗口,tcp
采用慢启动机制,采用2^n的数学模型来控制报文数量
采用2^n的好处是,一开始,报文数量少,能慢慢增加报文的数量,等待网络恢复;一旦网络恢复,因其增幅快的特性,能快速进入正常通信
但也不能一味的增长,我们需要准确探测到当前的拥塞窗口,当以2^n增长到某一阈值时,改为线性探测,知道导致网络拥塞,将新的阈值改为拥塞窗口的一半,继续采用慢启动机制…
2.2.7 延迟、捎带应答
当接受方接受到报文时,并不会立马做应答,而是会延迟一段时间,在这段时间内,应用层可能将数据取走,这样就能给发送方一个更大的窗口大小,以提高通信效率,我们把这种策略叫做延迟应答
而捎带应答,我们之间也见过,当给对方应答时,也想发送数据,就能把ACK和数据一并发送,tcp
三次握手就是做了捎带应答
2.3 面向字节流
对于udp
,发送方发的,就是接收方收的,不能灵活控制发送次数和接受次数
对于tcp
,发送方可以多次发送,接收方也能分多次接受 — 面向字节流
2.4 粘包问题
对于tcp
,接收方收到报文将数据放到接受缓冲区,对于应用层来讲,数据全是字符串,也就是各种数据黏在一起,怎么区分一个完整的数据 — 序列化与反序列化
3. TCP全连接队列
3.1 backlog
为了解释listen
的第二个参数backlog具体有何作用,将服务器不对任何连接accept
,并设置backlog
为2,将3个client与server连接
确实存在三个client->server的连接,三个server->client的连接,同时也证明accept
不参与三次握手的过程
当再有client连接时
client->server连接处于SYN_SENT
的状态,这表示SYN报文已经发出,但server没同意建立连接,同时没有server->client的连接
当sever来不及accept
时,允许client与server继续建立连接,但最多只能有 backlog + 1个连接
在OS中,来不及accept
的连接会以队列的方式管理起来,我们把管理这些连接的队列叫做全连接队列
3.2 全连接队列的原理
需要注意的是,不是指服务器只能接受backlog + 1个连接,而是来不及接受的连接最多只能是backlog + 1个
backlog的值不建议太大,也不能为0,如果太大,后面的连接就需要等待较长时间,如果为0,等待server需要accept连接时,还需要继续三次握手
当前server来不及accept,等待空闲了,直接从全连接队列中拿,本质是减少了服务器的闲置率,提高用户的体验
从内核层面,我们理解连接
4. tcpdump
sudo tcpdump -i any # 捕获任意报文
sudo tcpdump -i any tcp # 捕获任意tcp报文sudo tcpdump -i eth0 tcp # 捕获指定网络接口的tcp报文sudo tcpdump src host xxx and tcp # 捕获指定源ip的tcp报文
sudo tcpdump src host xxx and dst host xxx and tcp # 捕获指定源ip和目的ip的tcp报文sudo tcpdump port xxx and tcp # 捕获指定端口的tcp报文sudo tcpdump -n port xxx and tcp -w xxx.pcap # 将捕获的tcp报文写到文件中
sudo tcpdump -r xxx.pcap # 将文件中的报文信息显示
相关文章:

udp tcp协议
文章目录 1. UDP协议1.1 端口号1.2 UDP协议格式1.3 UDP特性1.4 报文的封装 2. TCP协议2.1 TCP协议格式2.2 TCP策略2.2.1 确认应答机制(ACK)序号与确认序号6个标志位序号的理解 2.2.2 超时重传机制2.2.3 连接管理机制三次握手四次挥手理解三次握手理解四次挥手 2.2.4 流量控制2.…...
C语言结构体详细讲解
文章目录 [TOC] 一、前言二、结构体2.1 结构体概念🎈2.2 结构体定义🎉2.3 结构体使用🎗️ 结尾 时间紧后面还有一些知识点这周内补上, 理解理解!(❁◡❁) 一、前言 在学习结构体之前,讲讲为什么会专门写一章博客来分享…...

公交车信息管理系统:实现交通数据的智能化处理
概述 在对系统进行设计之前,需要对选题进行需求分析、可行性分析、流程分析、数据字典等内容。根据需求分析阶段,大致确定用户使用系统所需要具有的功能模块需求,由此规划出系统需要设计的相关功能模块。根据可行性分析阶段,确定系…...
在 Windows 下生成 .tgz 文件的方法
方法 1:使用 7-Zip 7-Zip 是一个流行的免费压缩工具,支持生成 .tar.gz 格式。 步骤: 下载并安装 7-Zip。准备好要压缩的文件或文件夹。右键点击文件或文件夹,选择 7-Zip > 添加到压缩文件...。在弹出的对话框中:…...

编程式浪漫,100款圣诞树代码分享
最近这几天有很多小伙伴开始寻找各种各样的圣诞树代码,我们最常用的Java,Python,C语言,前端,都是可以实现的。小巫师,就在这里分享超火的圣诞树代码,源码分享! 01.HTML圣诞树源代码…...

Nacos的下载和启动(如何快速稳定下载在github中)
目录 Nacos的下载 下载加速器 在githup中找到Nacos 启动Nacos 访问Nacos Nacos的下载 下载加速器 首先,我们需要进入githup中,我们直接访问,肯定是访问不到的。 这里我们经常玩游戏的同学肯定知道steam,这个加速器。直接进入…...
python基础知识(六)
文章目录 连接Mysql数据库安装Mysql数据库连接数据库创建数据库创建数据表查询表是否存在设置主键插入数据批量插入查询、删除、更新数据 使用PyMySql连接数据库安装PyMySql连接数据库 连接MongoDB安装pymongo驱动在MongoDB创建库及数据插入文档查询数据修改数据文档排序删除数…...

神经网络-LeNet
LeNet在1990年被提出,是一系列网络的统称,包括了LeNet1~LeNet5,对于神经网络的学习者来说,大家对下面这个图一定很熟悉,该图是对LeNet的简化展示。 在LeNet中已经提出了卷积层、Pooling层等概念,只是但是由…...
es 中 terms set 使用
在 Elasticsearch 中,terms_set 查询通常用于在一个字段上进行多值匹配,并支持设置一个条件(例如最小匹配数量),让查询结果更具灵活性。为了展示如何使用 terms_set 查询,我们首先会创建一个索引࿰…...
绩效考核试题
1.2.绩效考核 ()通过财务、客户、内部运营、学习与成长4个角度,将组织战略目标逐层分解转化为细化指标,有差异地针对不同的指标进行不同时期的绩效评估,有助于组织战略目标的实现。 A目标管理法 B平衡计分卡法 C硬性分…...
停车管理系统:构建安全、便捷的停车环境
Tomcat 简介 只要学习Java Web项目就不得不学习Tomcat。Tomcat是一种免费的开源的一种Java Web项目的容器,完美继承了 Apache服务器的特性,并且里面添加可以自动化运行的Java Web组件,让Java Web项目可以完全的运行到Tomcat里面。对于特大型项…...

十四、从0开始卷出一个新项目之瑞萨RZN2L之栈回溯(Default_Handler/hartfault)
目录 一、概述 二、参考资料 三、代码 四、日志 五、定位函数调用 六、README和工具 一、概述 软件开发中常见的比较棘手的问题就是hartfault/Default_Handler/dump,俗称跑飞了。 参考cmbacktrace,在瑞萨RZN2L/T2M实现栈回溯,串口打印…...

联通光猫怎么自己改桥接模式?
环境: 联通光猫 ZXHN F677V9 硬件版本号 V9.0 软件版本号 V9.0.0P1T3 问题描述: 联通光猫怎么自己改桥接模式 家里用的是ZXHN F677V9 光猫,最近又搞了个软路由,想改桥接模式 解决方案: 1.拿到最新超级密码&…...

突围边缘:OpenAI开源实时嵌入式API,AI触角延伸至微观世界
当OpenAI宣布开源其名为openai-realtime-embedded-sdk的实时嵌入式API时,整个科技界都为之震惊。这一举动意味着,曾经遥不可及的强大AI能力,如今可以被嵌入到像ESP32这样的微型控制器中,真正地将AI的触角延伸到了物联网和边缘计算…...

springBoot Maven 剔除无用的jar引用
目录 Used undeclared dependencies found Unused declared dependencies found 当项目经过一段时间的开发和维护后,经常会遇到项目打包速度变慢的问题。这通常与项目中包含大量的jar依赖有关,这些依赖之间的关系错综复杂。这种情况在项目维护过程中是…...

malloc 分配大堆块(128KB)的一次探索
前言 一次意外执行了 malloc(0x5000),结构使用 gdb 调试发现其分配的位置在 TLS 区域,这令我不解(:最后去看了下 malloc 源码和 mmap 源码实现,发现似乎可能是 gdb 插件的问题,乐 场景复现 #include <…...
Android -- 双屏异显之方法二
Android – 双屏异显之方法二: DisplayManager PS: 1. 使用改方法主板需连接至少两个输出显示屏; 2. 副屏内部实现与MediaRouter下一样;使用方法 # 主屏activity内: private SecondDisplay secondDisplay;private void dualScreen3288() {D…...

电脑使用CDR时弹出错误“计算机丢失mfc140u.dll”是什么原因?“计算机丢失mfc140u.dll”要怎么解决?
电脑使用CDR时弹出“计算机丢失mfc140u.dll”错误:原因与解决方案 在日常电脑使用中,我们时常会遇到各种系统报错和文件丢失问题。特别是当我们使用某些特定软件,如CorelDRAW(简称CDR)时,可能会遇到“计算…...

使用RDMA技术构建无损网络
如何使用RDMA构建无损网络? 在深入研究RDMA和无损网络领域后,会经常遇到两个基本问题:为什么采用无损网络至关重要?这些先进技术有什么优势? 无损网络是一种新型的网络技术,它可以在不丢失数据包的情况下传…...
vscode 识别git目录
vscode 偶尔无法识别使用git 新托管的项目。 以下是我提供的解决方案——重启 git.enabled VS Code配置问题: 有时候,VS Code的配置可能会导致无法识别.git文件夹。确保你的VS Code配置中启用了Git的相关功能。你可以通过”Settings”(设置…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...