HTTP Keep-Alive模式

news2024/11/19 7:44:49

故事发生在10月份的一次面试经历中,本来我不想说出来丢人显眼,但是为了警醒自己和告诫后人,我决定写成博文发出来。因为在面试过程中,我讲在2009年写过QQ农场助手,在这期间深入学习了HTTP协议,而且在2010-05-18写了博文:HTTP协议及其POST与GET操作差异 & C#中如何使用POST、GET等。面试官说既然我熟悉HTTP协议,就问“当HTTP采用keepalive模式,当客户端向服务器发生请求之后,客户端如何判断服务器的数据已经发生完成?”

说实话,当时我懵了,一直没有关注过keepalive模式。我只知道:HTTP协议中客户端发送一个小请求,服务器响应以所期望的信息(例如一个html文件或一副gif图像)。服务器通常在发送回所请求的数据之后就关闭连接。这样客户端读数据时会返回EOF(-1),就知道数据已经接收完全了。我就这样被面试官判了死刑!!!说我完全停留在表面,没有深入(当时真的很受打击,一直自认为技术还不错!)。我当时真的很想找各种借口:

之前没有用到HTTP的keepalive模式,所以没有深入
好久没有用HTTP协议,细节忘了
实习的东西跟HTTP协议没有关系,用得少了就忘了
。。。。。。
觉得各种解释都是那么苍白无力!我再次感叹书到用时方恨少,也感叹一个人的时间是多么的有限(曾一度想成为一个IT专业全才),根本没有精力面面俱到,而且当没有真正使用一个东西的时候,往往会忽略掉很多细节。朋友如果你也答不上来,请认真细看下文,不要怀着浮躁了的心,说不定下次就有人问你这个问题。

1、什么是Keep-Alive模式?
我们知道HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议);当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。

File:HTTP persistent connection.svg

http 1.0中默认是关闭的,需要在http头加入"Connection: Keep-Alive",才能启用Keep-Alive;http 1.1中默认启用Keep-Alive,如果加入"Connection: close ",才关闭。目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了,所以是否能完成一个完整的Keep-Alive连接就看服务器设置情况。

2、启用Keep-Alive的优点
从上面的分析来看,启用Keep-Alive模式肯定更高效,性能更高。因为避免了建立/释放连接的开销。下面是RFC 2616上的总结:

By opening and closing fewer TCP connections, CPU time is saved in routers and hosts (clients, servers, proxies, gateways, tunnels, or caches), and memory used for TCP protocol control blocks can be saved in hosts.
HTTP requests and responses can be pipelined on a connection. Pipelining allows a client to make multiple requests without waiting for each response, allowing a single TCP connection to be used much more efficiently, with much lower elapsed time.
Network congestion is reduced by reducing the number of packets caused by TCP opens, and by allowing TCP sufficient time to determine the congestion state of the network.
Latency on subsequent requests is reduced since there is no time spent in TCP’s connection opening handshake.
HTTP can evolve more gracefully, since errors can be reported without the penalty of closing the TCP connection. Clients using future versions of HTTP might optimistically try a new feature, but if communicating with an older server, retry with old semantics after an error is reported.
RFC 2616(P47)还指出:单用户客户端与任何服务器或代理之间的连接数不应该超过2个。一个代理与其它服务器或代码之间应该使用超过2 * N的活跃并发连接。这是为了提高HTTP响应时间,避免拥塞(冗余的连接并不能代码执行性能的提升)。

3、回到我们的问题(即如何判断消息内容/长度的大小?)
Keep-Alive模式,客户端如何判断请求所得到的响应数据已经接收完成(或者说如何知道服务器已经发生完了数据)?我们已经知道了,Keep-Alive模式发送玩数据HTTP服务器不会自动断开连接,所有不能再使用返回EOF(-1)来判断(当然你一定要这样使用也没有办法,可以想象那效率是何等的低)!下面我介绍两种来判断方法。

3.1、使用消息首部字段Conent-Length
故名思意,Conent-Length表示实体内容长度,客户端(服务器)可以根据这个值来判断数据是否接收完成。但是如果消息中没有Conent-Length,那该如何来判断呢?又在什么情况下会没有Conent-Length呢?请继续往下看……

3.2、使用消息首部字段Transfer-Encoding
当客户端向服务器请求一个静态页面或者一张图片时,服务器可以很清楚的知道内容大小,然后通过Content-length消息首部字段告诉客户端需要接收多少数据。但是如果是动态页面等时,服务器是不可能预先知道内容大小,这时就可以使用Transfer-Encoding:chunk模式来传输数据了。即如果要一边产生数据,一边发给客户端,服务器就需要使用"Transfer-Encoding: chunked"这样的方式来代替Content-Length。

chunk编码将数据分成一块一块的发生。Chunked编码将使用若干个Chunk串连而成,由一个标明长度为0的chunk标示结束。每个Chunk分为头部和正文两部分,头部内容指定正文的字符总数(十六进制的数字)和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。

Chunk编码的格式如下:

Chunked-Body = *chunk
“0” CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF

hex-no-zero = <HEX excluding “0”>

chunk-size = hex-no-zero *HEX
chunk-ext = *( “;” chunk-ext-name [ “=” chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)

footer = *entity-header

即Chunk编码由四部分组成:1、0至多个chunk块,2、“0” CRLF,3、footer,4、CRLF.而每个chunk块由:chunk-size、chunk-ext(可选)、CRLF、chunk-data、CRLF组成。

4、消息长度的总结
其实,上面2中方法都可以归纳为是如何判断http消息的大小、消息的数量。RFC 2616对消息的长度总结如下:一个消息的transfer-length(传输长度)是指消息中的message-body(消息体)的长度。当应用了transfer-coding(传输编码),每个消息中的message-body(消息体)的长度(transfer-length)由以下几种情况决定(优先级由高到低):

任何不含有消息体的消息(如1XXX、204、304等响应消息和任何头(HEAD,首部)请求的响应消息),总是由一个空行(CLRF)结束。
如果出现了Transfer-Encoding头字段 并且值为非“identity”,那么transfer-length由“chunked” 传输编码定义,除非消息由于关闭连接而终止。
如果出现了Content-Length头字段,它的值表示entity-length(实体长度)和transfer-length(传输长度)。如果这两个长度的大小不一样(i.e.设置了Transfer-Encoding头字段),那么将不能发送Content-Length头字段。并且如果同时收到了Transfer-Encoding字段和Content-Length头字段,那么必须忽略Content-Length字段。
如果消息使用媒体类型“multipart/byteranges”,并且transfer-length 没有另外指定,那么这种自定界(self-delimiting)媒体类型定义transfer-length 。除非发送者知道接收者能够解析该类型,否则不能使用该类型。
由服务器关闭连接确定消息长度。(注意:关闭连接不能用于确定请求消息的结束,因为服务器不能再发响应消息给客户端了。)
为了兼容HTTP/1.0应用程序,HTTP/1.1的请求消息体中必须包含一个合法的Content-Length头字段,除非知道服务器兼容HTTP/1.1。一个请求包含消息体,并且Content-Length字段没有给定,如果不能判断消息的长度,服务器应该用用400 (bad request) 来响应;或者服务器坚持希望收到一个合法的Content-Length字段,用 411 (length required)来响应。

所有HTTP/1.1的接收者应用程序必须接受“chunked” transfer-coding (传输编码),因此当不能事先知道消息的长度,允许使用这种机制来传输消息。消息不应该够同时包含 Content-Length头字段和non-identity transfer-coding。如果一个消息同时包含non-identity transfer-coding和Content-Length ,必须忽略Content-Length 。

5、HTTP头字段总结
最后我总结下HTTP协议的头部字段。

1、 Accept:告诉WEB服务器自己接受什么介质类型,/ 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。
2、 Accept-Charset: 浏览器申明自己接收的字符集
Accept-Encoding: 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)
Accept-Language:浏览器申明自己接收的语言
语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等。
3、 Accept-Ranges:WEB服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。bytes:表示接受,none:表示不接受。
4、 Age:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。
5、 Authorization:当客户端接收到来自WEB服务器的 WWW-Authenticate 响应时,用该头部来回应自己的身份验证信息给WEB服务器。
6、 Cache-Control:请求:no-cache(不要缓存的实体,要求现在从WEB服务器去取)
max-age:(只接受 Age 值小于 max-age 值,并且没有过期的对象)
max-stale:(可以接受过去的对象,但是过期时间必须小于 max-stale 值)
min-fresh:(接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的缓存对象)
响应:public(可以用 Cached 内容回应任何用户)
private(只能用缓存内容回应先前请求该内容的那个用户)
no-cache(可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端)
max-age:(本响应包含的对象的过期时间)
ALL: no-store(不允许缓存)
7、 Connection:请求:close(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,断开连接,不要等待本次连接的后续请求了)。
keepalive(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求)。
响应:close(连接已经关闭)。
keepalive(连接保持着,在等待本次连接的后续请求)。
Keep-Alive:如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持连接多长时间(秒)。例如:Keep-Alive:300
8、 Content-Encoding:WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。例如:Content-Encoding:gzip
9、Content-Language:WEB 服务器告诉浏览器自己响应的对象的语言。
10、Content-Length: WEB 服务器告诉浏览器自己响应的对象的长度。例如:Content-Length: 26012
11、Content-Range: WEB 服务器表明该响应包含的部分对象为整个对象的哪个部分。例如:Content-Range: bytes 21010-47021/47022
12、Content-Type: WEB 服务器告诉浏览器自己响应的对象的类型。例如:Content-Type:application/xml
13、ETag:就是一个对象(比如URL)的标志值,就一个对象而言,比如一个 html 文件,如果被修改了,其 Etag 也会别修改,所以ETag 的作用跟 Last-Modified 的作用差不多,主要供 WEB 服务器判断一个对象是否改变了。比如前一次请求某个 html 文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得的 ETag 值发送给WEB 服务器,然后 WEB 服务器会把这个 ETag 跟该文件的当前 ETag 进行对比,然后就知道这个文件有没有改变了。
14、 Expired:WEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟WEB服务器验证了其有效性后,才能用来响应客户请求。是 HTTP/1.0 的头部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT
15、 Host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号。例如:Host:rss.sina.com.cn
16、 If-Match:如果对象的 ETag 没有改变,其实也就意味著对象没有改变,才执行请求的动作。
17、 If-None-Match:如果对象的 ETag 改变了,其实也就意味著对象也改变了,才执行请求的动作。
18、 If-Modified-Since:如果请求的对象在该头部指定的时间之后修改了,才执行请求的动作(比如返回对象),否则返回代码304,告诉浏览器该对象没有修改。例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT
19、 If-Unmodified-Since:如果请求的对象在该头部指定的时间之后没修改过,才执行请求的动作(比如返回对象)。
20、 If-Range:浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分给我,如果对象改变了,就把整个对象给我。浏览器通过发送请求对象的 ETag 或者 自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否改变了。总是跟 Range 头部一起使用。
21、 Last-Modified:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT
22、 Location:WEB 服务器告诉浏览器,试图访问的对象已经被移到别的位置了,到该头部指定的位置去取。例如:Location:http://i0.sinaimg.cn/dy/deco/2008/0528/sinahome_0803_ws_005_text_0.gif
23、 Pramga:主要使用 Pramga: no-cache,相当于 Cache-Control: no-cache。例如:Pragma:no-cache
24、 Proxy-Authenticate: 代理服务器响应浏览器,要求其提供代理身份验证信息。Proxy-Authorization:浏览器响应代理服务器的身份验证请求,提供自己的身份信息。
25、 Range:浏览器(比如 Flashget 多线程下载时)告诉 WEB 服务器自己想取对象的哪部分。例如:Range: bytes=1173546-
26、 Referer:浏览器向 WEB 服务器表明自己是从哪个 网页/URL 获得/点击 当前请求中的网址/URL。例如:Referer:http://www.sina.com/
27、 Server: WEB 服务器表明自己是什么软件及版本等信息。例如:Server:Apache/2.0.61 (Unix)
28、 User-Agent: 浏览器表明自己的身份(是哪种浏览器)。例如:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/2、0、0、14
29、 Transfer-Encoding: WEB 服务器表明自己对本响应消息体(不是消息体里面的对象)作了怎样的编码,比如是否分块(chunked)。例如:Transfer-Encoding: chunked
30、 Vary: WEB服务器用该头部的内容告诉 Cache 服务器,在什么条件下才能用本响应所返回的对象响应后续的请求。假如源WEB服务器在接到第一个请求消息时,其响应消息的头部为:Content-Encoding: gzip; Vary: Content-Encoding那么 Cache 服务器会分析后续请求消息的头部,检查其 Accept-Encoding,是否跟先前响应的 Vary 头部值一致,即是否使用相同的内容编码方法,这样就可以防止 Cache 服务器用自己 Cache 里面压缩后的实体响应给不具备解压能力的浏览器。例如:Vary:Accept-Encoding
31、 Via: 列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用什么协议(和版本)发送的请求。当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面添加 Via 头部,并填上自己的相关信息,当下一个代理服务器收到第一个代理服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的Via 头部,并把自己的相关信息加到后面,以此类推,当 OCS 收到最后一个代理服务器的请求时,检查 Via 头部,就知道该请求所经过的路由。例如:Via:1.0 236.D0707195.sina.com.cn:80 (squid/2.6.STABLE13)

HTTP 请求消息头部实例:
Host:rss.sina.com.cn
User-Agent:Mozilla/5、0 (Windows; U; Windows NT 5、1; zh-CN; rv:1、8、1、14) Gecko/20080404 Firefox/2、0、0、14
Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0、9,text/plain;q=0、8,image/png,/;q=0、5
Accept-Language:zh-cn,zh;q=0、5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0、7,*;q=0、7
Keep-Alive:300
Connection:keep-alive
Cookie:userId=C5bYpXrimdmsiQmsBPnE1Vn8ZQmdWSm3WRlEB3vRwTnRtW <-- Cookie
If-Modified-Since:Sun, 01 Jun 2008 12:05:30 GMT
Cache-Control:max-age=0
HTTP 响应消息头部实例:
Status:OK - 200 <-- 响应状态码,表示 web 服务器处理的结果。
Date:Sun, 01 Jun 2008 12:35:47 GMT
Server:Apache/2、0、61 (Unix)
Last-Modified:Sun, 01 Jun 2008 12:35:30 GMT
Accept-Ranges:bytes
Content-Length:18616
Cache-Control:max-age=120
Expires:Sun, 01 Jun 2008 12:37:47 GMT
Content-Type:application/xml
Age:2
X-Cache:HIT from 236-41、D07071951、sina、com、cn <-- 反向代理服务器使用的 HTTP 头部
Via:1.0 236-41.D07071951.sina.com.cn:80 (squid/2.6.STABLE13)
Connection:close请添加图片描述

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

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

相关文章

盐湖钛系提锂吸附剂

#盐湖钛系提锂吸附剂 盐湖钛系提锂吸附剂HPL900是一种高选择性高容量锂离子筛吸附剂。其通过纳米杂化、锂离子印迹等技术制备而成。该吸附剂活性纳米晶粒子对锂离子具有高效吸附性能&#xff08;其对锂的吸附容量大于10.0g Li/L&#xff09;&#xff0c;同时吸附位点对锂离子具…

哈希表(底层结构剖析-- 上)

文章目录 哈希表底层结构剖析哈希概念哈希冲突哈希函数 哈希冲突解决办法闭散列( 线性探测 二次探测)开散列 哈希表闭散列方法的模拟实现基本框架有关哈希数据的类插入函数删除函数查找函数增加仿函数将所有数据类型转换为整型 哈希表开散列方法的模拟实现(增加仿函数版) 哈希…

Visual Studio的安装注意

本文目前包含的内容&#xff1a; Visual Studio版本选择工作负载组建的选择安装后的环境配置 目录 1. 安装前1. 安装过程中2. 安装后注意 1. 安装前 安装版本选择&#xff1a; 一定不要选最新的版本&#xff0c;选3-5年前的稳定版本&#xff01;新版本会出很多bug。 1. 安装过…

银行数字化转型导师坚鹏:银行数字化转型创新与应用前沿

银行数字化转型创新与应用前沿 ——金融科技如何赋能银行数字化转型 课程背景&#xff1a; 数字化背景下&#xff0c;很多银行存在以下问题&#xff1a; 不清楚5G如何赋能银行数字化转型&#xff1f; 不清楚最新金融科技如何赋能银行数字化转型&#xff1f; 不了解银行…

自动驾驶落地如何降本?这家头部公司有自己的独特之处

一直以来&#xff0c;商用车智能化与乘用车有很多差异化&#xff0c;比如&#xff0c;B端客户对于规模车队的采购成本&#xff0c;智能化应用场景的适配性以及对自动驾驶更为务实的认知。 4月18日&#xff0c;2023上海车展&#xff0c;作为场景化新能源的自动驾驶全球领导者&am…

直播软件app开发:如何开发一个可以免费打扑克的直播应用?

作为一个技术开发人员&#xff0c;我深知直播软件app开发的重要性。在这个数字化时代&#xff0c;越来越多的人选择使用直播软件来分享自己的生活和与朋友互动。而随着技术的发展&#xff0c;直播软件也不断更新和改进&#xff0c;为用户提供更好的体验和功能。 对于开发者来说…

git merge、git pull和git fetch

git merge 合并分支&#xff0c;将目标分支合并到当前分支git fetch 更新远端分支&#xff0c;但不会merge到本地git pull 更新远端分支并merge到本地git pull git fecth git merge merge的意思为“合并”&#xff0c;git merge命令是用于将分支合并在一起的操作&#xff…

kafka_2.13-2.8.1环境搭建

本次kafka环境主要针对kafka2.x版本&#xff0c;运行kafka服务之前&#xff0c;需要先搭建zookeeper服务&#xff0c;因为kafka服务依赖zookeeper&#xff0c;kafka3.x版本后可以不需要手动搭建zookeeper了。 本文主要是介绍怎样搭建kafka2.8.1&#xff0c;关于kafka的操作&am…

matlab求解整数规划

一、整数规划 定义&#xff1a;数学规划中的变量&#xff08;部分或全部&#xff09;限制为整数时&#xff0c;称为整数规划。 若在线性规划模型中&#xff0c;变量限制为整数&#xff0c;则称为整数线性规划。 分类&#xff1a;&#xff08;1&#xff09;变量全部限制为整数时…

JUC多并发编程 内存模型

计算机硬件存储系统 因为有多级的缓存(CPU 和 物理主内存的速度不一致的)&#xff0c; CPU 的运行并不是直接操作内存耳饰先把内存里边的数据读到缓存&#xff0c;而内存的读和写操作的时候就会造成不一致的问题JVM 规范中试图定义一种 Java 内存模型(Java Memory Model, 简称…

【UE】倒计时归零时结束游戏

上一篇博客&#xff08;【UE】一个简易的游戏计时器&#xff09;完成了游戏时间每秒1的功能&#xff0c;本篇博客在此基础上完成倒计归零时结束游戏的功能 效果 步骤 1. 打开“ThirdPersonGameMode”&#xff0c;将剩余的秒数和分钟数的默认值分别设置为1和59 在事件图表中添…

全球首款车规级彩色激光大灯,这家中国供应商引领下一代显示交互

随着汽车智能化进程进入深水区&#xff0c;基于显示、照明的新技术正在成为新的聚焦点。无论是AR HUD&#xff0c;还是舱内多模态人机交互都在成为新的增量。而汽车独有的智能移动终端以及第三生活空间的未来属性&#xff0c;也在创造新的市场机会。 4月18日&#xff0c;全球领…

法规标准-ISO 16787标准解读

ISO 16787是做什么的&#xff1f; ISO 16787全称为智能运输系统-辅助泊车系统&#xff08;APS&#xff09;-性能要求和测试程序&#xff0c;其中主要描述了对APS系统的功能要求及测试规范 APS类型 根据目标停车位类型将APS系统分为两类&#xff1a; 1&#xff09;APS类型I&a…

北大POJ 1000 ~ 1009

1. AB &#x1f351; POJ1000 ab &#x1f354; 签到题 import java.io.*; import java.util.*; public class Main {public static void main(String args[]) throws Exception{Scanner cinnew Scanner(System.in);int acin.nextInt(),bcin.nextInt();System.out.println(…

开发常用的 Linux 命令3(文本处理、打包和压缩)

开发常用的 Linux 命令3&#xff08;文本处理、打包和压缩&#xff09; 作为开发者&#xff0c;Linux是我们必须掌握的操作系统之一。因此&#xff0c;在编写代码和部署应用程序时&#xff0c;熟练使用Linux命令非常重要。这些常用命令不得不会&#xff0c;掌握这些命令&#…

c提高学习——指针作为函数参数的输入特性

输入特性 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> //在主调函数分配内存 被调函数使用 void func(char *p) {strcpy(p, "hello world"); } void test01() {//在栈上分配内存char buf[1024] …

《使用循环做一些练习》---C语言

目录 前言&#xff1a; 1.练习专题 1.1打印1-100之间的奇数 1.2计算n的阶乘 1.3计算到达n阶乘的前m个阶乘相加 1.4演示字符串动态变化的效果 2.goto语句 ❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其它语言打好基础…

扬声器,打印机2键触摸VK3602K SOP8 2键2通道触摸检测芯片技术资料直接输出自动校准功能

型号&#xff1a;VK3602K 封装形式&#xff1a;SOP8 KPP2620 VK3602K具有2个触摸按键&#xff0c;可用来检测外部触摸按键上人手的触摸动作。该芯片具有较高的集成度&#xff0c;仅需极少的外部组件便可实现触摸按键的检测。 提供了2路直接输出功能,可通过IO脚选择输出电平。…

基于单片机的家庭防盗报警系统的设计与实现_kaic

基于单片机的家庭防盗报警系统 专业&#xff1a;物联网工程 摘要&#xff1a;本论文研究的是将AT89C52单片机芯片作为核心元器件的防盗报警系统,该系统除了具有直接报警的功能外,还额外增加了布防和红外感应的功能。和市场上的其他各类防盗报警器相比,该设计的不同之处在于它所…

KubeSphere 助力提升研发效能的应用实践分享

作者&#xff1a;卢运强&#xff0c;主要从事 Java、Python 和 Golang 相关的开发工作。热爱学习和使用新技术&#xff1b;有着十分强烈的代码洁癖&#xff1b;喜欢重构代码&#xff0c;善于分析和解决问题。原文链接。 我司从 2022 年 6 月开始使用 KubeSphere&#xff0c;到目…