当前位置:网站首页>我的勇敢对线之路--详细阐述,浏览器输入URL发生了什么
我的勇敢对线之路--详细阐述,浏览器输入URL发生了什么
2022-07-06 20:22:00 【梦想成为光头强!】
前言
这道题其实学过TCP的同学们都能说出来一二,也就是大致的过程是怎样的,但是如果拉出来详细的梳理一遍,还是有很多的知识点需要整理一下的。细想一下,如果面试官问:你说一下浏览器输入URL之后发生了什么吧,然后巴拉巴拉一会会就讲完了,那可能我们就错失了一个很好的展示自己的机会。所以为了避免这种情况的发生,这篇博客就诞生了。
一丶小小数据包的独白–HTTP协议
浏览器首先干了啥?肯定是先解析你输入的URL
,然后生成一个给Web服务器发送的请求信息
。
那就开始我们的解析之路
1.关于URL–URL的格式解析
首先就是解析URL,那么来让我们看看,一个URL里面包含了那些信息。
用一个例子来展示一下,比如说:
http:// 其实就是 协议名称://
www.server.com 就是web服务器
/dir1/file.html 目录文件的路径
所以一个URL组成还是很简单的,可能有细心的铁子会问了,你看看!你上面的蓝色部分说了呀,可以省略的!
那你省略了的话,你怎么知道源文件路径是什么呢?啊,关于这个问题,看下图
当我们省略了文件路径的时候
如果没有文件路径,就代表访问根目录事先设置的默认文件夹,比如说:
/index.html
再或者说/default.html
2.数据包的诞生–HTTP的那些事
好了,URL解析完了吧,知道了协议名称
,知道了Web服务器的地址
,还知道了要访问的文件
,那么是不是就该给我们远方的服务器朋友发送请求消息了?几日不见,为兄需要你的帮助,特此寄信,以表紧急。
那么就开始写信,写信是要有格式的,不然目的服务器老哥一看:这么久不见,好不容易写个信你还这态度?你在敷衍谁?所以我们的数据包生成一定要遵循HTTP协议。
关于HTTP协议的方法名称常见的有两种(用的比较多!!!!不是只有这两种,这里就介绍两种)
请 求 报 文 \color{red}请求报文 请求报文
一般情况下来说,如果说你想给服务器老哥寄点土特产你就用POST,如果你想要让老哥给你寄点土特产你就用GET。
响 应 报 文 \color{red}响应报文 响应报文
这里其实有一个问题我这里想提一下,就是不论是请求报文或者说是响应报文,都有一个消息体,这里的话有很多常见的消息头,我挺想在这里写点东西,但是考虑到整体的篇幅,我这里不敢做过多阐述,有兴趣的可以看我下面这两篇博客。(甚至还包括HTTPS,单双向认证什么,状态码,这里其实挺多东西可以说的)
其实仔细一想哈,关于这个部分我是不是写个博客把其中有意思的东西拉出来单独锤一遍?可以可以!!这篇博客写完之后就搞!!
那么到了这里,我们的一个简简单单,遵循HTTP协议的数据包
就生成啦。那么问题来啦,我怎么过去呢?万一我跑到一半被人套了黑麻袋打晕带走了呢?我的目的地是哪里呢?是不是瞬间感觉氛围感拉满?但是纵使前路风雨很大,该走还是要走的,就这样,我们的数据包就走上了自己的寻亲之路!
二丶打听亲戚地址–关于地址查询
浏览器解析URL并且生成数据包之后,就要委托操作系统把消息发给服务端Web服务器
。但是发送你要知道发给谁,所以就需要查询服务器域名对应的IP地址
,你委托操作系统发消息,肯定要知道目的地的IP,也就是主机的地址呀。所以我们就需要得到一个老大哥的帮助,也就是根服务器DNS,它保存了Web服务器域名
和IP
地址的对应关系。
1.江南江北一条街–关于域名的层级关系
为什么我这个段落要起这个名字?因为我本来用它的下一句话做标题,当然这个不重要,回归正题。
DNS中的域名是用句点分割的,比如www.server.com
,这里的句点代表了不同层次的界限
。在我们的域名中,越靠右的域名层级越高(别问我为啥是这样的,你要问外国人为啥是这习惯)。根域在顶层,下一层是com顶级域,再到server.com。所以其实域名关系就是一个树
根DNS服务器 => 顶级域DNS服务器(com) => 权威DNS服务器(server.com)
根域的DNS服务器信息保存在互联网的所有DNS服务器中,所以说只要客户端找到随便一个DNS服务器,就都可以通过它找到根DNS服务器,然后再一路顺藤摸瓜找到位于下层的某台DNS服务器。
2.苍茫的寻亲之路–关于域名解析
1.首先就是当前服务器发出一个DNS请求给本地的DNS服务器,问:本地的DNS服务器老哥,你知不知道
www.server.com
老哥的在哪里呀?(悄咪咪问老哥的IP地址
,这里本地的DNS服务器就是客户端TCP/IP设置当中填写的DNS服务器地址)
2.本地域名服务器(DNS服务器)收到了客户端的请求之后,如果缓存表格里找到了www.server.com
(PS:局域网),那就把对应主机的IP地址返回。如果说没有找到,那么本地的DNS服务器就会跑去问它的根域名服务器
老大哥:大哥,www.server.com
小老弟的IP地址是啥?老大哥日理万机,他不会直接告诉你,而是会告诉你去哪里找。
3.根DNS服务器收到了来自本地DNS服务器的请求,看到了后置是.com
,就说:www.server.com
是你的二哥.com
的地盘,你去问问它,然后本地DNS服务器收到了顶级域名.com
的地址。
4.本地DNS服务器再次发起请求问:二哥,你能告诉我www.server.com的地址嘛?顶级域名服务器收到了来自本地DNS服务器的请求,说:我给你你的三哥:权威服务器server.com
的地址,那是它的地盘,你在哪里可以找到答案。
5.然后本地DNS服务器又屁颠屁颠跑去问server.com
的权威DNS服务器:三哥,www.server.com的IP地址是啥呀?server.com老哥一看,吼?这不是我的地盘上那谁谁嘛?然后就把对应主机的IP地址告诉了本地DNS服务器。
6.本地DNS服务器最后跑了回来:数据报小老弟,你的亲戚的IP地址是XXX。也就是把这个DNS服务器返回给了客户端。
到了这里,数据包就知道目的地是哪里了,但是自己啥也没有,所以一个人去有点危险,它就要找点小伙伴和自己一起出发。
3.关于笔者在这里的补充
这里的查找不是说一开始就直接去根DNS服务器查询的,而是
查找浏览器缓存
查找系统缓存
查找路由器缓存
查找运行商缓存
最后如果还是找不到,就要去根DNS服务器查找啦。
三丶成群结伴一起上路–数据包的封装
我们的小小数据包终于到了这一步了,但是到现在,家门还没迈出去,但是没关系,继续往下走,我们通过DNS获得了IP地址,就可以把HTTP的传输工作就给操作系统中的协议栈
,参考我们的TCP五层模型。
首先就是在应用层封装好数据包之后,调用Socket库
,来委托协议栈工作(传输层和网络层),协议栈的上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,它们两会接受应用层的委托执行收发数据的操作。协议栈的下面一半是用 IP 协议控制网络包收发操作,在互联网上传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由 IP 负责的。
这里提一下,IP协议中还包括了ICMP协议和ARP协议
。
ICMP 用于告知网络包传送过程中产生的错误以及各种控制信息。
ARP 用于根据 IP 地址查询相应的以太网 MAC 地址。
IP协议下面的网卡驱动程序
(数据链路层)就负责控制网卡硬件,而最下面的网卡
则负责最后的实际收发操作。数据包一看,好家伙,这确实没人帮不行呀,所以就呼朋唤友,准备集合一起出发上路。
1.可靠传输小老弟–TCP
<1>简略说一下TCP协议
HTTP协议是基于TCP协议传输的,,先简略说一下TCP协议
关于HTTP协议没说太多,这里TCP协议是绕不开了
源端口号和目的端口号:源主机对应的应用程序的进程和目的主机对应的应用程序的进程。
序列号:防止包乱序
确认号:确定对方是否收到
状态位:维护双方的状态
窗口大小:可靠传输机制和效率传输机制的保障所在。
啊,不行了,简略的阐述一下就是上面这些,这里我要偷个懒,如果有认真看的老哥,我再骗一波浏览。关于TCP协议的详细解释看这里
<2>三次握手
HTTP协议发送数据包之前肯定是要先建立连接,这里就是我们的TCP协议发挥作用的时候了。连接的过程,也就是我们常说的三次握手,三次握手只是维护双方计算机的一个状态,情况如下:
1.初始状态双方都是Close,先是服务端处于监听状态,也就是LISTEN
2.客户端向服务端发送SYN数据包,申请建立连接。发送数据包后客户端处于SYS_SENT状态。
3.服务端收到后,向客户端返回一个SYN数据包(这个数据包包含了SYN和ACK包,这是捎带应答机制)。返回之后服务端处于SYN_RVCD状态。
4.客户端收到服务端的SYN包后,向服务端返回一个ACK数据包。
5.等待一段时间之后,客户端进入ESTABLISHED状态。而服务端一收到AKC数据包就立刻进入ESTABLISHED状态。
三次握手的目的是确保双方都有收发消息的能力。
这里还有几个小点是我想说一下的
1. 如 何 查 看 T C P 连 接 状 态 \color{red}{1.如何查看TCP连接状态} 1.如何查看TCP连接状态
可以在Linux中通过netstat-napt命令查看
2. T C P 分 割 数 据 \color{red}{2.TCP分割数据} 2.TCP分割数据
啥意思呢?就是小小数据包路途中要带的东西太多了,没办法一次性过去。换个比较正常点的说法,就是HTTP数据包消息太长了,超过了MSS
的长度,这个时候TCP就要把HTTP的数据拆分成一块块的数据发送,而不是一次性发送所有数据。
首先来让我们了解一下一个完成数据包是咋样的(被TCP和IP等联合帮助之后的完整数据包)
MTU:就是一个数据包的最大长度,以太网中一般为1500字节。
MSS:除去IP和TCP头部之后,一个网络包所能容纳的TCP数据的最大长度。
数据会被以MSS的长度为单位进行拆分,拆分出来之后的每一块数据都会被放进单独的一个网络包当中,也就是给每个被拆分的数据加上TCP头信息,然后交给IP模块来发送数据。
2. T C P 报 文 生 成 \color{red}{2.TCP报文生成} 2.TCP报文生成
TCP协议里面有两个端口,一个是浏览器监听的窗口(通常随机生成),还有一个是Web服务器监听的端口(HTTP默认端口是80
,HTTPS默认端口是443
)。双方建立连接之后,TCP报文中的数据部分就存放在HTTP头部+数据,组装好TCP报文之后,就把它交给下层,也就是网络层来处理。这个时候的数据包如下
此时小小数据包激动地不能自己,好了!我有TCP这个可靠的小老弟了,不用再担心安全问题了,那么我接下里该往哪里走呢?
这里多插一句,如果说对于TCP携带数据包括其他一些问题可以看我下面这篇博客,关于读者们想要了解的知识应该在里面都有。
2.远程定位小老弟–IP
TCP模块在执行连接,收发,断开等各个阶段操作的时候,都需要委托IP模块将数据封装成网络包发送给通信对象。那我们先来看看IP协议的格式
这里IP协议格式里面我们需要注意到两个地方
源地址IP:也就是客户端的IP地址
目标IP:也就是服务端的IP地址,也就是通过域名解析获得的Web服务器IP
因为HTTP经过TCP传输,所以IP包头的协议号
,就是06(十六进制)
,表示是TCP协议。那这里就有小伙伴问了,我目的IP地址,但是我自身的IP地址是什么呢?这里就是看下面了
关于多网卡多IP情况
如果说此时我有多个网卡,那么此刻无疑就有多个IP地址,我怎么知道那个是我要用的网卡呢?这个时候就要用到我们的路由表
规则,来判断一下,那个网卡可以作为源IP
。
这个时候我们就要查看当前系统的路由表了,比如说Linux系统中,我们可以通过命令route -n
来查看。举个例子
Destination:目的地址
GateWay:路由器的IP地址
Genmask:子网掩码
这里我们假设我们的目的IP地址是192.168.10.200 。
先和enth0
也就是第一条目
的子网掩码进行按位与运算
可以发现结果和目标地址Destination不一样,然后和enth1
也就是第二条目
的子网掩码进行按位与运算
然后发现得出来的结果和Destination
一样,所以就用eth1网卡的ID地址作为源IP地址。
这里需要特别说明一下,如果说所有的条目里面没有一个Destination能够匹配的上的,那么这个时候就会轮到我们的第三条目(这里以图中为例),这是默认网关,它的目标地址和子网掩码都是0.0.0.0
,它最后会把接收到的包发给路由器。
到了这里,我们的远程定位工作就做好啦,这个时候我们数据包,啊!不对,网络包(小老弟升级了)就变成了下面这个样子
数据包此时内心狂喜!!!!!
我是有IP小老弟护着的人!它会给我指路,让我有了远程定位的能力,不会在网络中迷茫。可是!目的地是目的地呀,我接下里去哪里呢?
3.两点传输小老弟–MAC
生成了IP头部之后,网络包还需要在IP头部之前加上MAC头部,具体样子大概是这种
我们的MAC包头是需要发送方的MAC地址和接收方的MAC地址的,因为你要用于两点之间的传输不是?所以一般在TCP/IP通信里面,MAC包头的协议类型只使用:
0800:IP协议
0806:ARP协议
<1>局域网
这里发送方的就比较容易了
每一个网卡生产的时候,他就写入了ROM里,把这个值读取出来,写入到MAC头部就好。
但是接收方的这里就比较暧昧了,因为我们知道了下一条的目的IP和最终的IP地址。这里要怎么做呢?就要涉及到我们的ARP协议
ARP协议会在以太网当中进行喊话:这个IP地址是谁的?把你的MAC地址给我,然后就会有人回答:这个IP地址是我的,我的MAC地址是xxxxx。如果说对方和自己在同一个子网当中,那么MAC地址就完成了。
当然,这里的话也不是一上来就直接喊话的。
1.首先查询ARP缓存,其中如果说保存了IP地址对应的MAC地址,那么就不需要ARP查询,直接使用ARP缓存中的地址。
2.如果不存在,那么就首先基于当前主机的IP和目的IP,分别和本机的子网掩码进行按位与运算,如果得到的网络号一致,那么就进行喊话!也就是把目的MAC设置为FF:FF:FF:FF:FF:FF,然后发送到所有相连接的主机进行ARP广播查询。
<2>广域网
这个时候问题就来了呀,你根据IP地址你查不到下一跳的MAC地址呀,你喊话也没用,都不在同一网段了,那么怎么搞?那就先把下一跳的MAC地址设置为路由器的MAC地址,然后准备由网卡接收再发送给交换机,最后由交换机交给路由器处理。
4.城门出口–网卡
IP生成的网络包仅仅是存放在内存中的一串二进制数字信息,没有办法真正的送给对方,所以我们需要把数字信息转化为电信号,才可以在网线上传输。那负责这一执行的就是网卡,控制网卡还需要靠网卡驱动程序。
网卡驱动从IP模块获取到包之后,会将其复制到网卡的缓存区当中,接着会在其开头加上报头和起始帧分解符,在末尾加上FCS也就是用于检测错误的帧校验序列
然后网卡会把包转化为一个电信号,通过网线发送出去。
5.大哥来送别–交换机
首先,交换机是一个生活在二层网络设备的老大哥,交换机大哥一听这么多老弟要走,肯定走之前是要送别一下,毕竟感情深厚。
在电信号到达网线接口的时候,交换机里面的模块进行接收,然后
交换机模块将电信号转化为数字信号
转化为数字信号以后,老大哥左瞅瞅,右看看:小老弟们,东西带全没有呀?
这一步也就是通过数据包末尾的错误校验帧系列码来检验错误。
如果没有问题,那么老大哥就可以放心的让它们出发了
校验完毕之后,没有问题就放到缓存区。
以上的这些流程和网卡的操作有些类似,但是具体来说还是有些区别,因为工作方式不同。
计算机网卡本身就具有MAC地址,并通过核对收到的包的MAC地址来判断是不是发给自己的,如果不是就丢弃。
而交换机的端口不核对接收方的MAC地址,而是直接接收所有的包放在缓存区。
所以区别就是:交换机的端口不具有MAC地址
把包放入缓存区之后,接下来需要查询一下这个包的接收方的MAC地址,是否已经在MAC地址表中有记录。这里交换机的MAC地址表主要有两个部分
第一个就是设备的MAC地址
第二个就是该设备连接在交换机的那个端口上
所以交换机就会根据MAC地址表查找MAC地址,然后把信号发送到相对应的端口上。
如果找不到对应的MAC地址?
如果说MAC地址表中没有对应的MAC地址,怎么搞?这里找不到MAC地址可能有两个原因
1.可能因为具有该地址的设备还没有向交换机发送过包
2.可能因为很久没有发送过包导致工作地址被交换机删除
这种情况下,交换机就会把这个包发送到除了源端口之外的所有端口上,别担心这样会产生什么问题,因为只有对应的接受者才会接收到这个包,其他设备就会直接忽略了,因为大家都很忙,没有时间处理与自己无关的事物。
也不用担心会造成网络拥堵问题,网络上发的包很多很多,你多几个完全不会有啥影响,而且这一次发送之后拿到了响应包就会把该对应关系写进MAC地址表,所以不会有问题。
此外,如果说接收方的地址是一个广播地址,交换机也会把包发送到所有的端口
MAC地址:FF:FF:FF:FF:FF:FF
IP地址:255.255.255.255
到了这个时候,数据包就离开生自己养自己的子网啦!即将步入新的世界!数据包感动的对大哥说:蟹蟹大哥给我送到出境口,我要出远门啦。
6.出境大门–路由器
1.交换机和路由器的区别
网络包经过交换机之后,就会到达路由器,并且在这里被转发到下一个路由器或者
目标设备,这里也需要查询表来判断包转发的目标,这里和交换机有些类似,但是
工作方式不同。
路由器:基于IP设计,俗称三层网络设备,路由器的各个端口都有MAC地址和IP地址。
交换机:基于以太网设计,俗称二层网络设备,没有一个端口有MAC地址,而网管型的交换机有IP地址
2.路由器的原理
路由器的端口有MAC地址,所有它可以成为以太网的接收方和发送方;他还有IP地
址,所有从这里讲它和网卡一样。
首先它会接收发给自己的以太网包,再由路由器查询转发目标,再由对应的端口作为
发送方将以太网包发送出去。
3.路由器包的接收操作
首先,电信号到达网线接口部分,路由器当中的模块会把电信号转化为数字信号,然
后通过末尾的FCS(错误校验序列码)进行错误校验。然后检查MAC头部中的接收
方MAC地址,有问题就丢掉,没有问题就放到缓存区。
4.查询路由表确定输出端口
完成包接收操作之后,路由器就会去掉包开头的MAC地址,毕竟你MAC地址的作用就
是发送包到路由器,用完了就直接丢掉好吧(MAC小老弟被无情抛弃),然后路由
器会根据IP头部中的内容进行包的转发
先查询路由表
然后就是每个条目的子网掩码和目的IP地址进行按位与运算,看得出来的结果也就
是对应条目的目的地址,也就是第一行的Destination是否匹配一致,如果说你没
找到,那么就选择默认路由
5.发送操作
现在就到了发送阶段。首先还是根据路由表的网关列判断对方的地址
如果网关是一个IP地址,那么这个地址就是我们要转发的目标地址,证明还未抵达终点,还需要继续转发
如果网关为空,那么IP头部中的接收方IP地址就是要转发的目标地址,也就是终于找到IP包头里的目标地址说明终点即将到达。
差不多就是这个样子,如果说网关的地址为空,那么IP头部中的IP地址就是要转发的目标地址啦。
知道了IP地址,接下来路由表会根据ARP协议查询MAC地址,并将查询的结果作为接收方的MAC地址,还是一样的,先查缓存,查不到再进行ARP查询请求。
发送方MAC地址就是输出端口的MAC地址
发送方的以太类型字段填写0080(十六进制)表示IP协议
完成之后,就会将其转化为电信号并且通过端口发送出去,然后发送的网络包达到下一个路由器,下一个路由器接收缓存之后再次转发,一直转发一直转发,最后就到了目的地。所以中途一直变化的是MAC地址,源IP地址和目的IP始终不会改变。因为MAC地址在以太网内进行两个设备之间的包传输。
6.关于MAC地址获取时候的广域网问题
什么意思呢?就是你的根据你的目的IP,查询不到下一跳的MAC地址,喊话也喊不到的时候,你怎么搞?注意了哈,这里喊话喊不到不是喊了之后没人回应得到的结果,而是在拿到目的IP地址,然后根据路由器的IP和目的IP和当前网段内的子网号进行按位与运算之后发现结果不一致所得到的的结果。
这个时候就要基于NAPT协议,把我们的源IP和源端口(port)转化为公网的。同时基于路由器的路由功能,查找离目的IP最近的一条路线的同时设置下一跳的MAC地址。
为什么说需要把局域网的IP和端口设置为公网的IP和端口呢?因为接收端返回的响应数据报,目的端口和目的IP无法使用局域网IP和端口。
7.有朋自远方来
最后数据包就抵达了服务器啦,从底向上,开始扒衣服(我这样形容是不是不太好?)
先扒MAC头部,查看目的MAC,如果和服务器自己的MAC地址符合就收起来。
再扒IP头,和自己的IP地址也符合,就转给TCP。
再扒TCP头,里面有序列号,如果是我想要的,就返回一个ACK应答包,不是就丢弃。TCP头部还有端口号,HTTP的服务器正在监听这个端口号。然后服务器就知道HTTP进程正在等待这个包,这就是它想要的,于是TCP就把这个包发送给HTTP进程。
HTTP一看,嗷,原来这个请求是想访问一个网页,然后就把这个网页封装在HTTP响应报文中,然后再经由TCP,IP,MAC包装之后,出发回家。不过这次的源IP和目的IP和来的时候进行了调换。
衣服穿好了就来到了网卡,再到交换机给送到边界口,也就是路由器,再由路由器一蹦一跳的回到了家。
等回到家之后,再被扒一次衣服,然后把数据交给浏览器,浏览器去渲染网页,就这样,浏览器输入URL的流程彻底完结。
总结
一个数据包,去探亲的路总是充满坎坷,路上得有朋友相助:可靠传输TCP,远程定位IP,下一站位置引路人MAC等等。大家集合之后就一起出发,在交换机和路由器的帮助之下,一路坎坷的抵达了目的地。这一路的经历,让数据包深深的认识到了网络世界的浩瀚和秩序性,至此,故事告一段落,撒花完结!!!
边栏推荐
- 【C语言】 题集 of Ⅸ
- 22.(arcgis api for js篇)arcgis api for js圆采集(SketchViewModel)
- LAB1配置脚本
- 安装 torch 0.4.1
- The version control of 2021 version is missing. Handling method
- HMS Core 机器学习服务打造同传翻译新“声”态,AI让国际交流更顺畅
- 杰理之开启经典蓝牙 HID 手机的显示图标为键盘设置【篇】
- 密码学系列之:在线证书状态协议OCSP详解
- Intelligent static presence detection scheme, 5.8G radar sensing technology, human presence inductive radar application
- Matlab Error (Matrix dimensions must agree)
猜你喜欢
Appx code signing Guide
Laravel php artisan 自动生成Model+Migrate+Controller 命令大全
input_delay
About Tolerance Intervals
Stored procedures and functions (MySQL)
About Confidence Intervals
Not All Points Are Equal Learning Highly Efficient Point-based Detectors for 3D LiDAR Point
R数据分析:cox模型如何做预测,高分文章复现
Shangsilicon Valley JVM Chapter 1 class loading subsystem
华为小米互“抄作业”
随机推荐
函数重入、函数重载、函数重写自己理解
Make (convert) ICO Icon
Jerry's question about DAC output power [chapter]
华为小米互“抄作业”
杰理之在非蓝牙模式下,手机连接蓝牙不要跳回蓝牙模式处理方法【篇】
Appx代码签名指南
The solution of unable to create servlet file after idea restart
Enumeration general interface & enumeration usage specification
杰理之开 BLE 退出蓝牙模式卡机问题【篇】
变量、流程控制与游标(MySQL)
Optimization of application startup speed
OC, OD, push-pull explanation of hardware
Sorting operation partition, argpartition, sort, argsort in numpy
Stored procedures and functions (MySQL)
树莓派设置wifi自动连接
Jerry's ble exiting Bluetooth mode card machine [chapter]
20.(arcgis api for js篇)arcgis api for js面采集(SketchViewModel)
MOS transistor realizes the automatic switching circuit of main and auxiliary power supply, with "zero" voltage drop and static current of 20ua
杰理之开启经典蓝牙 HID 手机的显示图标为键盘设置【篇】
Not All Points Are Equal Learning Highly Efficient Point-based Detectors for 3D LiDAR Point