GB28181系列三:SIP消息格式

news2024/11/30 13:15:56

        我的音视频/流媒体开源项目(github)

        GB28181系列目录

目录

一、SIP消息Header字段        

二、SIP URI(URL)

三、SIP路由机制

1、路由机制介绍

2、严格路由(Strict Routing)与松散路由(Louse Routing)

3、总结 

四、SIP消息示例

1、注册-带鉴权

2、呼叫

3、MESSAGE示例


一、SIP消息Header字段        

        上一篇文章介绍了SIP的各种信令和两个用户之间通话的SIP信令交互流程,本篇将详细介绍SIP的消息格式。常见的SIP方法有:INVITE、ACK、PRACK、BYE、CANCEL、REGISTER、OPTIONS。在这些类型的SIP消息头部中包含的常见字段如下表所示:

Header含义说明举例
Call-ID由本地设备(Client)生成,全局唯一,每次呼叫这个值唯一不变Call-ID: asd88asd77a@1.2.3.4
From表示请求的发起者From: sip:user1@domain.com;tag=49583
To表示请求的接收者To: sip:user2@domain.com
ViaVia头域是被服务器插入request中,用来检查路由环的,并且可以使response根据via找到返回的路

Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse

Max-Forwards用于表示这个包最多可以传送多少跳,每经过一跳都会减一当Max-Forwards==0系统会返回483。默认为70Max-Forwards: 70
Contact包含源的URI信息,用来给响应方直接和源建立连接用

Contact: sip:192.168.100.1:1111

Content-Type指明消息体的类型 (SDP会话描述协议)Content-Type: text/plain;Content-Type: application/sdp; Content-Type: application/cpim;
Content-Length指明消息体的字节大小Content-Length: 18

        下面解释一下其中比较难理解的几个字段,之前已经解释了dialog(对话)、session(会话)、transaction(事务),忘了的可以去上一篇再看一下。

        1、Via:

        Via头域是收集经过的设备信息。一个SIP消息每经过一个Proxy(包括主叫),都会被加上一个Via头域,当消息到达被叫后,Via头域就记录了请求消息经过的完整路径。被叫将这些Via头域原样copy到响应消息中(包括各Via的参数,以及各Via的顺序),然后下发给第一个Via中的URI,每个Proxy转发响应消息前都会把第一个Via(也就是它自己添加的Via)删除,然后将消息转发给新的第一个Via中的URI,直到消息到达主叫。

        如下图所示,表示了Via的作用:

        2、tag:

        用于在SIP消息中的 To 和 From 头部区分和标识不同的参与者。区分同一个会话中不同的SIP实体,尤其是当一个用户(或服务器)有多个可能的通信终端时。Tag 允许SIP协议区分从同一源发起的多个请求,通常是随机字符串或特定标识符。

        From: From: Alice <sip:alice@atlanta.com>;tag=client1
        To: To: Bob <sip:bob@biloxi.com>;tag=client2
        在这个例子中,发起方 Alice 使用了 client1 作为 From 的Tag,接收方 Bob 则使用了 client2 作为 To 的Tag。

        Call-ID、From(tag)、To (tag)这三个字段相同代表是同一个dailog对话。

        3、branch:

        branch值相同,代表同一个 transaction(事务) Branch,每发起一个transaction(事务)都要重新生成一个branch;对于遵循RFC3261规范的实现,这个branch参数的值必须用magic cookie”z9hG4bK”打头. 其它部分是对“To, From, Call-ID头域和Request-URI”按一定的算法加密后得到。

二、SIP URI(URL)

        再来看一下SIP URI格式,SIP消息中有很多地方都用到了SIP URI,其中包括To、From、Contact这些头域,还有说明请求目的端的Request-URI。SIP URI里的信息说明了联系SIP资源(用户)的具体方式。

        SIP URI以方案名sip打头,紧接着是一个冒号“:”,然后是用户名加@,@后面是主机名或IPv4/ IPv6地址,端口是可选的,如果有端口,用冒号“:”分隔,最后是URI参数列表,参数列表中的参数以分号“;”作为分割符。示例如下:

sip:joseph.fourier@transform.example.org:5060;transport=udp;user=ip;method=INVITE;ttl=1;maddr=240.101.102.103?Subject=FFT

        示例中的?用于分隔查询参数(Query Parameters)与 URI的路径部分。它后面的内容通常是一些附加的参数,用于为SIP请求提供额外的信息。查询参数是键值对形式的,多个参数之间用 & 分隔。 

        有些SIP URI没有用户名,只有主机名或IP,比如说REGISTER请求的Request-URI。在上面实例中,端口使用的是SIP的标准端口5060。对于SIP URI来说,如果没有描述端口,那么就假定它使用的是默认端口5060;对于SIPS URL来说,则是5061。transport参数说明传输协议选用UDP,这也是SIP的缺省选择。transport参数的可选值还有TCP、TLS和SCTP。

        user参数来说明URI的用户名部分是否为电话号码。它的缺省值为ip,说明不是电话号码。如果是电话号码,那么它的值为应该设为phone。

        method参数说明所使用的方法。默认值是INVITE。这个参数对To、From头域及Request-URI来说没有意义,但对于注册的Contact头域或转移的Refer-To头域来说是有用处的。

        ttl参数是生存时间,只有当maddr参数包含多播地址,而transport参数包含udp时,才能使用该参数。默认值是1。此值作用于多播会话广播。

        maddr通常包含请求应当被定向到的多播地址,覆盖URI中主机部分的地址。它还可以携带备用服务器的单播地址。

        method、maddr、ttl及header这几个参数不允许出现在To或From头域中,但可以在Contact头域或Request-URI使用。除了这些参数之外,SIP URI可以包含其它用户定义参数。

三、SIP路由机制

         参考:

        【SIP协议路由机制】_sip路由机制-CSDN博客

        SIP 协议路由规则详解_sip route-CSDN博客

1、路由机制介绍

        SIP的路由机制是SIP协议很重要的部分,通过路由机制,才使得一个呼叫请求在VOIP网络的众多Proxy节点中,找到正确的目的端。

        SIP路由包括:请求路由(Route)与响应路由(Via),响应路由(Via)已经在上面说明,下面重点看一下请求路由(Route)。

        请求路由(Route)的生成是通过头域Record-Routes进行收集。

        路由收集(Record-Route):请求消息被代理转发前,由代理服务器插入请求消息中,这样可以使该对话中将来的请求仍能经过该Proxy。

        路由(Route):发起端收到响应确认消息后,根据响应消息中的Record-Route头域获得一个Proxy列表,用来指示后续请求消息的路由;同样,目的端收到请求消息后,根据请求消息的Record-Route头域获得一个Proxy列表,用来指示后续请求消息的路由。

        Route和Record-Route具体处理过程如下:

        在一个请求消息的传输过程中,Proxy也可能会添加一个Record-Route头域,这样当消息到达被叫后里面就有会有0个或若干个Record-Route头域。被叫会将这些Record-Route头域并入自己的路由集,随后被叫在发送请求(和Record-Route属于同一个dialog里面)消息时就会使用该路由集构造一系列Route头域,以便对消息进行路由。

        另外,被叫会像上面对待Via头域一样,将Record-Route头域全部原样copy到响应消息中返回给主叫。主叫收到响应消息后也会将这些Record-Route头域并入路由集,只是它会将其反序。该会话中的后续请求(和Record-Route属于同一个dialog里面)消息的Route头域就会通过路由集构造。

        目的(Contact):联系人或最终的目的地地址。不管是请求端还是目的端,当发起请求是目的地址就是Contact。请求消息或响应消息必须携带Contact头域,告诉对方自己的联系地址。

        如下图所示,是Contact头域示例:

2、严格路由(Strict Routing)与松散路由(Louse Routing)

  • 严格路由(Strict Routing):可以理解为比较“死板”的理由机制,这种路由机制在SIP协议的前身RFC 2534中定义,其机制非常简单。
  • 松散路由(Louse Routing):该路由机制较为灵活,也是SIP路由机制的灵魂所在,在RFC 3261中定义。
  • 混合路由:如果在一条路由的路径中,既有严格路由又有松散路由,我们称之为混合路由。
     

        如何判断一个Proxy是否为严格路由还是松散路由?

        根据请求消息中的Route字段中设置的SIP URI一个lr的属性进行判断,当携带有“lr”属性就表明该Proxy为松散路由Proxy,否则就是严格路由。如:

Route:sip:a.b.c.d;lr

        这就是表示这个地址所在的Proxy是一个Loose Router。需要注意的是"lr"属性是在Proxy添加Record-Roud时设置的。

严格路由的处理步骤如下:

  • 接收到的消息的request-URI必须是自己的URI;
  • 把第一个Route头域“弹”出来,并把其中的URI作为新的request-URI;
  • 然后把该消息路由到新的request-URI;

松散路由的处理步骤如下:

  • Proxy首先会检查消息的request-URI是不是属于自己所负责的域。如果是,它就会通过定位服务将该地址“翻译”成具体的联系地址并以此替换掉原来的request-URI;否则,它不会动request-URI;
  • Proxy检查路由表中的第一个地址是否为自己,如果是则从表中删除;
  • Loose Router首先会检查Request URI是否为自己插入到路由表中的地址,如果不是,则不作处理;如果是,则取出Route字段的最后一个地址作为Request URI地址,并从Route字段中删去最后一个地址;
  • Loose Router检查下一跳是否为Strict Router。如果不是,不处理;否则,将Request URI插入到路由表表尾,并用下一跳地址Strict Router的地址)更新Request URI;如果路由表为空,则路由给Request URI;否则,路由到路由表表首地址。

3、总结 

        Via头域是为了给一个请求消息的响应消息留后路,而Record-Route就是为了给该请求消息之后的请求消息留后路。

        Record-Route头域不用来路由,而只是起到传递信息的作用。

        Route头域才是用来指示路由。

        Contact头域是用来告诉对方我的联系地址。

        再来看一个交互示例,就可以很清晰的知道路由的机制了。

四、SIP消息示例

1、注册-带鉴权

过程如下:

  • 请求端192.168.2.161发送注册消息给192.168.2.89服务器
  • 服务器对192.168.2.161发送“401 Unauthorized”信息给请求端,提示请求端需要带上鉴权信息重新注册
  • 请求端带上鉴权信息后(带有“Authorization”头字段)重新向服务器注册
  • 服务器验证鉴权头的正确性,如果鉴权成功,给请求端发送200 OK消息。若失败,继续发送401消息。

        请求端192.168.2.161发送注册消息给192.168.2.89服务器:

REGISTER sip:192.168.2.89 SIP/2.0

Via: SIP/2.0/UDP 192.168.2.161:8021
Max-Forwards: 70
From: <sip:01062237493@192.168.2.89>;tag=efca469543ce4788a6a6a2c7b66cd01f;epid=de4504430d
To: <sip:01062237493@192.168.2.89>
Call-ID: c88a247a74b54a8c9e676bdde3bba6c9@192.168.2.161
CSeq: 1 REGISTER
Contact: <sip:192.168.2.161:8021>;methods="INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER"
User-Agent: RTC/1.2.4949 (BOL SIP Phone 1005)
Event: registration
Allow-Events: presence
Content-Length: 0

        服务器对192.168.2.161发送401 Unauthorized信息给请求端,提示请求端需要带上鉴权信息重新注册:

SIP/2.0 401 Unauthorized

Via: SIP/2.0/UDP 192.168.2.161:8021
From: <sip:01062237493@192.168.2.89>;tag=efca469543ce4788a6a6a2c7b66cd01f;epid=de4504430d
To: <sip:01062237493@192.168.2.89>;tag=-001893-38ba013ba3dde36e
Call-ID: c88a247a74b54a8c9e676bdde3bba6c9@192.168.2.161
CSeq: 1 REGISTER
Allow: INVITE,ACK,OPTIONS,BYE,CANCEL,REGISTER,INFO,UPDATE,PRACK,REFER,SUBSCRIBE,NOTIFY,MESSAGE
Contact: <sip:192.168.2.89:14010>
Content-Length: 0
WWW-Authenticate: Digest realm="192.168.2.89", qop="auth", nonce="e17d377c3d2d9c343e26576a7fd04738481dfc10", opaque="", stale=FALSE, algorithm=MD5

        请求端192.168.2.161通过Authorization头字段带上鉴权头信息,发送一个新的REGISTER消息:

REGISTER sip:192.168.2.89 SIP/2.0

Via: SIP/2.0/UDP 192.168.2.161:8021
Max-Forwards: 70
From: <sip:01062237493@192.168.2.89>;tag=efca469543ce4788a6a6a2c7b66cd01f;epid=de4504430d
To: <sip:01062237493@192.168.2.89>
Call-ID: c88a247a74b54a8c9e676bdde3bba6c9@192.168.2.161
CSeq: 2 REGISTER
Contact: <sip:192.168.2.161:8021>;methods="INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER"
User-Agent: RTC/1.2.4949 (BOL SIP Phone 1005)
Authorization: Digest username="01062237493", realm="192.168.2.89", qop=auth, algorithm=MD5, uri="sip:192.168.2.89", nonce="e17d377c3d2d9c343e26576a7fd04738481dfc10", nc=00000001, cnonce="12660455546344082314666316435946", response="f57e47ce03162293b9ced07362ce2b79"
Event: registration
Allow-Events: presence
Content-Length: 0

        服务器验证鉴权头的正确性,如果鉴权成功,给请求端发送200 OK消息。若失败,继续发送401消息:

SIP/2.0 200 OK

Via: SIP/2.0/UDP 192.168.2.161:8021
From: <sip:01062237493@192.168.2.89>;tag=efca469543ce4788a6a6a2c7b66cd01f;epid=de4504430d
To: <sip:01062237493@192.168.2.89>;tag=-001894-a5eb977c8969aa51
Call-ID: c88a247a74b54a8c9e676bdde3bba6c9@192.168.2.161
CSeq: 2 REGISTER
Allow: INVITE,ACK,OPTIONS,BYE,CANCEL,REGISTER,INFO,UPDATE,PRACK,REFER,SUBSCRIBE,NOTIFY,MESSAGE
Contact: sip:192.168.2.161:8021
Content-Length: 0
Expires: 3600

        关于鉴权的方式参考我的另外一篇文章RTSP系列二:RTSP协议鉴权_rtsp鉴权-CSDN博客

2、呼叫

        主叫端发起INVITE请求:

INVITE sip:33010602001310019325@10.64.49.218:7100 SIP/2.0
Via: SIP/2.0/UDP 10.64.49.44:7100;rport;branch=z9hG4bK1839167633
From: <sip:130909115229300920@10.64.49.44:7100>;tag=868569348
To: <sip:33010602001310019325@10.64.49.218:7100>
Call-ID: 2074790969
CSeq: 20 INVITE
Contact: <sip:130909115229300920@10.64.49.44:7100>
Content-Type: Application/SDP
Max-Forwards: 70
User-Agent: Hikvision
Subject: 33010602001310019325:0,130909115229300920:0
Content-Length: 216

v=0
o=33010602001310019325 0 0 IN IP4 10.64.49.44
s=Play
c=IN IP4 10.64.49.44
t=0 0
m=video 5494 RTP/AVP 96 97 98
a=rtpmap:96 PS/90000
a=rtpmap:97 MPEG4/90000
a=rtpmap:98 H264/90000
a=recvonly
y=0999999999

        被叫端振铃 100 Trying:

SIP/2.0 100 Trying
Via: SIP/2.0/UDP 10.64.49.44:7100;rport=7100;branch=z9hG4bK1839167633
From: <sip:130909115229300920@10.64.49.44:7100>;tag=868569348
To: <sip:33010602001310019325@10.64.49.218:7100>
Call-ID: 2074790969
CSeq: 20 INVITE
User-Agent: Hikvision
Content-Length: 0

        被叫端返回200 OK:

SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.64.49.44:7100;rport=7100;branch=z9hG4bK1839167633
From: <sip:130909115229300920@10.64.49.44:7100>;tag=868569348
To: <sip:33010602001310019325@10.64.49.218:7100>;tag=3330812776
Call-ID: 2074790969
CSeq: 20 INVITE
Contact: <sip:130909113319427420@10.64.49.218:7100>
Content-Type: Application/SDP
User-Agent: Hikvision
Content-Length: 162

v=0
o=33010602001310019325 0 0 IN IP4 10.64.49.44
s=Play
c=IN IP4 10.64.49.218
t=0 0
m=video 5514 RTP/AVP 96
a=rtpmap:96 PS/90000
a=sendonly
y=0060205514

        主叫端收到200 OK,向被叫端返回ACK确认连接:

ACK sip:130909113319427420@10.64.49.218:7100 SIP/2.0
Via: SIP/2.0/UDP 10.64.49.44:7100;rport;branch=z9hG4bK3589109049
From: <sip:130909115229300920@10.64.49.44:7100>;tag=868569348
To: <sip:33010602001310019325@10.64.49.218:7100>;tag=3330812776
Call-ID: 2074790969
CSeq: 20 ACK
Contact: <sip:130909115229300920@10.64.49.44:7100>
Max-Forwards: 70
User-Agent: Hikvision
Content-Length: 0

        主叫端结束通话 BYE:

BYE sip:130909113319427420@10.64.49.218:7100 SIP/2.0
Via: SIP/2.0/UDP 10.64.49.44:7100;rport;branch=z9hG4bK2928302365
From: <sip:130909115229300920@10.64.49.44:7100>;tag=868569348
To: <sip:33010602001310019325@10.64.49.218:7100>;tag=3330812776
Call-ID: 2074790969
CSeq: 21 BYE
Contact: <sip:130909115229300920@10.64.49.44:7100>
Max-Forwards: 70
User-Agent: Hikvision
Content-Length: 0

        被叫端返回200 OK:

SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.64.49.44:7100;rport=7100;branch=z9hG4bK2928302365
From: <sip:130909115229300920@10.64.49.44:7100>;tag=868569348
To: <sip:33010602001310019325@10.64.49.218:7100>;tag=3330812776
Call-ID: 2074790969
CSeq: 21 BYE
User-Agent: Hikvision
Content-Length: 0

3、MESSAGE示例

        以上面的流程为例:

        步骤1:User1发送MESSAGE请求到代理服务器。

MESSAGE sip:user2@domain.com SIP/2.0

Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse
Max-Forwards: 70
From: sip:user1@domain.com;tag=49583
To: sip:user2@domain.com
Call-ID: asd88asd77a@1.2.3.4
CSeq: 1 MESSAGE
Content-Type: text/plain
Content-Length: 18

user2, come here.


        步骤2:代理服务器转发User1的MESSAGE请求给USER2。代理服务器收到步骤1请求,到数据库中查找User2(注册过程中生成数据库),随后生成步骤2的数据。


MESSAGE sip:user2@domain.com SIP/2.0
Via: SIP/2.0/TCP proxy.domain.com;branch=z9hG4bK123dsghds
Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse;
                                              received=1.2.3.4
Max-Forwards: 69
From: sip:user1@domain.com;tag=49394
To: sip:user2@domain.com
Call-ID: asd88asd77a@1.2.3.4
CSeq: 1 MESSAGE
Content-Type: text/plain
Content-Length: 18

user2, come here.


        步骤3:User2收到User1的消息后,回复200 OK给代理服务器。直接回应(200-OK) 没有Body,也不携带Contact头域。

SIP/2.0 200 OK
Via: SIP/2.0/TCP proxy.domain.com;branch=z9hG4bK123dsghds;
                                            received=192.0.2.1
Via: SIP/2.0/TCP user1pc.domain.com;;branch=z9hG4bK776sgdkse;
                                               received=1.2.3.4
From: sip:user1@domain.com;tag=49394
To: sip:user2@domain.com;tag=ab8asdasd9
Call-ID: asd88asd77a@1.2.3.4
CSeq: 1 MESSAGE
Content-Length: 0


        步骤4:代理服务器转发200 OK回复给User1。代理服务器收到回复后,去掉最顶端的Via,转发如下消息给User1。

SIP/2.0 200 OK

Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse;
                                              received=1.2.3.4
From: sip:user1@domain.com;;tag=49394
To: sip:user2@domain.com;tag=ab8asdasd9
Call-ID: asd88asd77a@1.2.3.4
CSeq: 1 MESSAGE
Content-Length: 0

        系列四将会对SIP的其他内容进行讲解。

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

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

相关文章

mvn-mac操作小记

1.安装brew 如果报错&#xff0c;Warning: /opt/homebrew/bin is not in your PATH. vim ~/.zshrc&#xff0c;最后一行追加 export PATH“/opt/homebrew/bin:$PATH” source ~/.zshrc 2.安装brew install maven mvn -version查看路径 Maven home: /opt/homebrew/Cellar/mav…

算法与数据结构练习——异或

知识点讲解&#xff1a; 一、异或操作定义&#xff1a; 异或是指相同为0&#xff0c;不同为1&#xff0c;也可理解为无进位相加&#xff01;&#xff01; 很重要&#xff01;&#xff01; 二、关于异或运算的几个性质&#xff1a; 1.0^NN &#xff08;0和任何数异或都…

STM32G4系列MCU的Direct memory access controller (DMA)功能介绍之二

目录 概述 1 DMA通道 1.1 可编程数据大小 1.2 指针增量 2 通道配置 2.1 配置步骤 2.2 通道状态和禁用通道 3 模式应用 3.1 循环模式&#xff08;内存到外设/外设到内存的传输&#xff09; 3.2 内存到内存模式 3.3 Peripheral-to-peripheral模式 3.4 编程转移方向&a…

【一文读懂】大语言模型

学习参考 项目教程&#xff1a;中文教程 代码仓库&#xff1a;代码地址 仓库代码目录说明&#xff1a; requirements.txt&#xff1a;官方环境下的安装依赖 notebook&#xff1a;Notebook 源代码文件 docs&#xff1a;Markdown 文档文件 figures&#xff1a;图片 data_base&…

注册表修改键盘位置

1.winr 输入 regedit 2.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout 3.右键Keyboard Layout->新建->二进制值->取名Scancode Map 4.右键Scancode Map&#xff0c;修改如下 //第一列 自动生成序号&#xff0c;不用管 第一行 输入8个00 第二…

服务器密码错误被锁定怎么解决?

当服务器密码错误多次导致账号被锁定时&#xff0c;解决方法需要根据服务器的操作系统&#xff08;如 Linux 或 Windows &#xff09;和具体服务器环境来处理。以下是常见的解决办法&#xff1a; 一、Linux 服务器被锁定的解决方法 1. 使用其他用户账号登录 如果有其他未被…

shell脚本编写练习2

1.准备阶段 在根目录下创建一个目录来存储shell脚本 mkdir /s3 2.题目 1. 使用case实现成绩优良差的判断 #!/bin/bash# 假设成绩存储在变量GRADE中 read -p "请输入成绩&#xff08;0-100&#xff09;&#xff1a;" GRADE# 使用case语句进行判断 case $GRADE in[…

清远榉之乡托养机构探讨:自闭症的本质辨析

当人们谈及自闭症时&#xff0c;常常会产生一个疑问&#xff1a;自闭症是精神类疾病吗&#xff1f;今天&#xff0c;清远榉之乡托养机构就来为大家解开这个疑惑。 榉之乡大龄自闭症托养机构在江苏、广东、江西等地都有分校&#xff0c;一直致力于为大龄自闭症患者提供专业的支持…

基于PoE交换机的智慧停车场监控组网应用

伴随城市发展快速&#xff0c;汽车保有量也不断增长&#xff0c;导致停车管理问题也愈发凸显。针对包括路侧停车位、地面停车场、地下停车场等场景的停车管理需求&#xff0c;通常会部署监控设备进行车位监测、现场安全监测等&#xff0c;助力构建智能化停车管理。因此如何为分…

.net XSSFWorkbook 读取/写入 指定单元格的内容

方法如下&#xff1a; using NPOI.SS.Formula.Functions;using NPOI.SS.UserModel;using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;using OfficeOpenXml.FormulaParsing.Excel.Functions.Numeric;/// <summary>/// 读取Excel指定单元格内容/// </summa…

10个Word自动化办公脚本

在日常工作和学习中&#xff0c;我们常常需要处理Word文档&#xff08;.docx&#xff09;。 Python提供了强大的库&#xff0c;如python-docx&#xff0c;使我们能够轻松地进行文档创建、编辑和格式化等操作。本文将分享10个使用Python编写的Word自动化脚本&#xff0c;帮助新…

红日靶场-5

环境搭建 这个靶场相对于前几个靶场来说较为简单&#xff0c;只有两台靶机&#xff0c;其中一台主机是win7&#xff0c;作为我们的DMZ区域的入口机&#xff0c;另外一台是windows2008&#xff0c;作为我们的域控主机&#xff0c;所以我们只需要给我们的win7配置两张网卡&#…

[Java]微服务之分布式事务

介绍 下单业务&#xff0c;前端请求首先进入订单服务&#xff0c;创建订单并写入数据库。然后订单服务调用购物车服务和库存服务: 购物车服务负责清理购物车信息库存服务负责扣减商品库存 问题分析: 下单过程中, 订单服务创建订单, 插入自己的数据库, 执行成功购物车服务, 清…

存储结构及关系(一)

学习目标 描述数据库的逻辑结构列出段类型及其用途列出控制块空间使用的关键字获取存储结构信息 段的类型 段是数据库中占用空间的对象。它们使用数据库数据文件中的空间。介绍不同类型的段。 表 表是在数据库中存储数据的最常用方法。表段用于存储既没有集群也没有分区的表…

cesium 3dtile ClippingPlanes 多边形挖洞ClippingPlaneCollection

原理就是3dtiles里面的属性clippingPlanes 采用ClippingPlaneCollection&#xff0c;构成多边形来挖洞。 其次就是xyz法向量挖洞 clippingPlanes: new this.ffCesium.Cesium.ClippingPlaneCollection({unionClippingRegions: true, // true 表示多个切割面能合并为一个有效的…

AMD的AI芯片Instinct系列介绍

AMD最强AI芯片发布&#xff01; 在旧金山举行的Advancing AI 2024大会上&#xff0c;AMD推出Instinct MI325X AI加速器&#xff08;以下简称MI325X&#xff09;&#xff0c;直接与英伟达的Blackwell芯片正面交锋。 现场展示的数据显示&#xff0c;与英伟达H200的集成平台H200 …

【大数据学习 | Spark调优篇】Spark之内存调优

1. 内存的花费 1&#xff09;每个Java对象&#xff0c;都有一个对象头&#xff0c;会占用16个字节&#xff0c;主要是包括了一些对象的元信息&#xff0c;比如指向它的类的指针。如果一个对象本身很小&#xff0c;比如就包括了一个int类型的field&#xff0c;那么它的对象头实…

基于深度学习的卷积神经网络十二生肖图像识别系统(PyQt5界面+数据集+训练代码)

本研究提出了一种基于深度学习的十二生肖图像识别系统&#xff0c;旨在利用卷积神经网络&#xff08;CNN&#xff09;进行图像分类&#xff0c;特别是十二生肖图像的自动识别。系统的核心采用了两种经典的深度学习模型&#xff1a;ResNet50和VGG16&#xff0c;进行图像的特征提…

kali linux 装 virtual box 增强工具 Guest Addition

kali linux 装 virtual box 增强工具 Guest Addition install Virtual Box Guest Addition in kali linux 搞了一下午&#xff0c;最终发现是白折腾。 kali linux 自带 virtual box 的增强工具。 kali linux 2021.3 之后的版本都是自带virtual box 增强工具 解决方法 直接…

vue3请求接口报错:Cannot read properties of undefined (reading ‘data‘)

文章目录 报错内容解决方案 报错内容 Cannot read properties of undefined (reading ‘data’) 解决方案 响应未按预期返回 确保服务器返回的数据结构符合预期。例如&#xff0c;服务器可能返回了一个错误响应&#xff0c;而不是预期的 JSON 数据。 检查响应 在 response 拦…