目录
前言
HB/ACKNACK
Preemptive HB and ACKNACKs
Participant Discovery
Endpoint Discovery
Endpoint Liveliness
Resent Participant Announcements
QoS Modifications
Dispose and Unregister Messages
Gap Messages
Content Filtered Topic
TopicQuery Creation
在我们上网时难免会因为这样那样的问题对通信产生疑问。当我们产生了疑问之后,这里推荐使用wireshark进行抓包分析。不是吹牛,wireshark真的是一款实用有效的必备“良药”。
wireshark是最流行的网络嗅探器之一,能在多种平台上抓取和分析网络包,windows/Linux/Mac等,拥有非常友好的界面。
追溯大学期间的《计算机网络》,就是下面这本书。全靠死记硬背才把OSI七层模型,TCP/IP五层模型(也有说是四层模型,没关系)记下来,考完试然后就又忘记了。这时候又要介绍“大哥”了,如果我当时接触了wireshark,是不是就可以很形象生动的去认识网络分层,扯多了,拉不出*来,还怨地球啊!
言归正传,下面通过wireshark将RTPS数据包进行扒光欣赏(剖析学习)。下面图暂时先不贴了,等后面有条件了在贴图。
FBI Warning: 理解下面内容需要对RTPS有最基本的认识。
使用可靠通信时,DataWriter将会对每一包用户数据进行消息确认。HB消息可以周期性的单独发送,也可以嵌在其他数据包中进行发送。HB消息用来提醒DataReader收到了哪一些数据,把收到的数据信息反馈给DataWriter,这时候DataReader就会通过ACKNACK进行反馈,确认哪些收到,哪些没有收到。
DDS可靠性协议是通过HB和ACKNACK实现的。DataReader对于DataWriter的HB回答是通过ACKNACK进行回复的。
在“传统”的情况下,DataRader和DataWriter匹配成功,ACKNACK只能被动的实现对HB的反馈。然而Connext DDS却实现了一种叫做“Preemptive ACKNACK”的机制,换句话说,当DataReader和一个DataWriter刚刚完成了发现,此时DataWriter尚未向DataReader发送任何HB信息,DataReader却迫不及待的向DataWriter发送了ACKNACK,这个ACKNACK就是“Preemptive ACKNACK”,使得DataReader快速跟上DataWriter的节奏。
“Preemptive ACKNACK”被wireshark标记为下图所示的形式,readerSNState的bitmapBase字段设置为0,这就表明了该消息是“Preemptive ACKNACK”。
“Preemptive HB”是另一种对于发现进程的优化。但是wireshark并没有像ACKNACK一样被标记为Preemptive。这是因为HB消息本身没有内部状态可以将其进行标记。“Preemptive HB”是在DataWriter和DataReader刚刚匹配后发送的消息,与周期HB消息区分开,而他自身并没有任何状态。
在participant发现期间,默认情况下,participant将向其目标方发送5条通知(使用非可靠的方式,因此也就不会看到HB和ACKNACK)。上面的5是可以通过DiscoveryConfig策略中的 initial_participant_announcements字段进行设置的,体现到wireshark抓包显示就是被标注为DATA(p)的数据包。
在participant的整个声明周期内,都会周期性发送DATA(p),用来声明自己还活着。默认情况下,周期是30秒,当然也可以修改。这里不做赘述。
端点的发现是在participant发现完成之后触发的。端点发现数据包使用可靠的通信进行交互,这表明通过wireshark抓包会发现HB和ACKNACK。
端点的发现其实就是DataReader和DataWriter的相互发现,发现的数据包以DATA(r)和DATA(w)的方式体现在wireshark中。
前面提到了participant在活着的情况下是通过DATA(p)告诉其他人的,那么现在DataReader和DataWriter也需要通过一种方式做相同的事情。
我们可以将DataWriter和DataReader的该过程配置为自动或者手动的。当配置为手动时,assert_liveliness()用来手动声明其生命状态。调用此方法,会在wireshark中抓到DATA(m)的数据包。当配置自动化时,就无需再调用该方法了。
还有一种情况,就是配置liveliness为自动发现时,DATA(m)会周期性的出现在wireshark中,其实也是在声明其生命。
当participant收到后加入的participant发送来的DATA(p)后,他会像其他所有的participant发送DATA(P)。
当程序在运行时对某些可以修改的QOS进行了修改,那么新修改的qos需要告知其他匹配的实体,就需要通过DATA(p)进行该操作了。
在wireshark中还可以看到被标记为DATA(U) 和DATA(D)形式的数据包。其实这些数据包就是DATA(p),只不过被赋予了一层其他的含义,在网络包分析中占有一定的地位,才对其进行了重命名。
U对应unregister的消息
D对应dispose的消息
该消息是从DataWriter发送给DataReader的。
思考这样一种情况,当我在DataWriter端使用内容过滤,那么DataWriter只将部分数据发送给DataReader,为了告知DataReader该情况,就会通过GAP消息来进行沟通。
再思考另一种情况,当使用部分可靠通信的情况下(配置keep_last_N),DataWriter的发送队列会进行数据的覆盖,当队列中的历史数据将要被覆盖,而DataReader还未对此消息进行确认时,DataWriter也会发送GAP消息。
订阅端应用创建和修改content filtered topic,会触发消息的交互,该消息是通过DATA(r)数据包进行交互的。
DataReader调用create_topic_query(),Connext DDS 会将TopicQueries信息通知给其他的participant和DataWriter。
该通知会使用内置的writer和reader进行通信。
本文链接:https://www.ngui.cc/zz/2317221.html