项目任务
1.研究一种可用于本项目中多台计算机进行通信的通信协议——ZMQ。
2.学习ZMQ发布订阅模式的代码编写,针对一对一,一对多,多对一三种模式分别进行测试。
3.测试两台电脑在同一局域网下利用ZMQ通信协议进行通信的延迟和丢包性能。
实验过程
1.ZMQ简介
ZeroMQ是个类似于 Socket 的一系列接口,他跟 Socket 的区别是:普通的 socket 是端到端的(1:1的关系),而 ZMQ 却是可以N:M 的关系,人们对 BSD 套接字的了解较多的是点对点的连接,点对点连接需要显式地建立连接、销毁连接、选择协议(TCP/UDP)和处理错误等,而 ZMQ 屏蔽了这些细节,让你的网络编程更为简单。ZMQ 用于 node 与 node 间的通信,node 可以是主机或者是进程。
ZMQ有三种通信模式:分别为请求应答模式、发布订阅模式以及推拉模式,本项目y拟采用发布订阅模式,主要是考虑到本项目中的协同建图的这种多对一的模式,适用于单项数据的传递。
2.ZMQ发布订阅模式代码编写及性能测试
首先需要在github上下载并安装libzmq以及cppzmq源码包,然后通过在原有代码的基础上分别加入发布订阅的代码,实现该功能。
github代码地址:https://github.com/search?q=libzmq
发布订阅的C++代码可参考该篇博客:https://blog.csdn.net/stpeace/article/details/82890127
最终通过稍微修改代码完成如下三种情况的测试。
(1)一对一(一个发布,一个订阅)
准备工作:需要在程序中指定发送及接收端的通信协议,IP地址,端口号,建立连接。需要指定发布端指定发送数据的频率,1s,2s等等,不指定的话就按照程序指令执行的速度一直发送,大约1s可发30万包。
测试效果:
测试结论:发布者不管谁是订阅者,一直发送消息,存在缓冲区。订阅者也不管谁是发布者,只要是这个连接内的数据,就会从缓冲区读取数据。并且订阅者只会读取当前发送的最新数据。
(2)一对多(一个发布,多个订阅)
准备工作: 发布者指定发送到的端口号,两个订阅者指定发布者的IP地址及相同的端口号,建立到同一连接。这里指定发布者1s发一次数据。
测试效果:
测试结论:两个订阅者可以同时接收发布者发来的相同的数据。
(3)多对一(多个发布,一个订阅)
准备工作:发布者指定两个不同的端口号,两个订阅者分别对应两个不同的端口号进行连接。(5555/5556)。这里指定两个发布者都是每隔1s发一次数据,且其中一个发送正数,另一个发送负数。
测试效果:
测试结论:多个发布者,一个订阅者时,订阅者会同时接收两个发布者的信息,交叉存储。
3.ZeroMQ通讯协议丢包以及延迟测试
测试方法:两台电脑连接同一局域网,其中一台电脑每隔一秒发送一个数据包,数据包中包括当前数据包编号以及发送时获取的本地时间,订阅者接收数据并记录接收对应编号数据包的本地时间,最终存储到TXT文件中,来分析是否有丢包和延迟现象发生。
测试结果(很小的一部分)整个大概测试将近800个:
server i=1
send time is : Thu Sep 19 21:25:14 2019
receive time is : Thu Sep 19 21:25:14 2019
server i=2
send time is : Thu Sep 19 21:25:15 2019
receive time is : Thu Sep 19 21:25:15 2019
server i=3
send time is : Thu Sep 19 21:25:16 2019
receive time is : Thu Sep 19 21:25:16 2019
server i=4
send time is : Thu Sep 19 21:25:17 2019
receive time is : Thu Sep 19 21:25:17 2019
server i=5
send time is : Thu Sep 19 21:25:18 2019
receive time is : Thu Sep 19 21:25:18 2019
server i=6
send time is : Thu Sep 19 21:25:19 2019
receive time is : Thu Sep 19 21:25:19 2019
初步测得:在秒级的情况下,ZeroMQ通信协议并未发现延迟和丢包现象。
接下来,在毫秒级情况下测试,测试结果如下:
server i=1
send time is : Sat Sep 21 19:52:47 2019
send_time(ms) is : 1569066767644
receive time is : Sat Sep 21 19:52:47 2019
receive_time(ms) : 1569066767715
server i=2
send time is : Sat Sep 21 19:52:48 2019
send_time(ms) is : 1569066768644
receive time is : Sat Sep 21 19:52:48 2019
receive_time(ms) : 1569066768715
server i=3
send time is : Sat Sep 21 19:52:49 2019
send_time(ms) is : 1569066769644
receive time is : Sat Sep 21 19:52:49 2019
receive_time(ms) : 1569066769716
server i=4
send time is : Sat Sep 21 19:52:50 2019
send_time(ms) is : 1569066770644
receive time is : Sat Sep 21 19:52:50 2019
receive_time(ms) : 1569066770716
结论:秒级仍然相同,然后毫秒级就是不太稳定,有的时候最大差30ms,有的时候最大差60ms,有的时候差80ms。
然后交换两台机器测试,发现接收时间在发送时间之前,目前认为该结论不太准确,由于不同电脑的本地时间差在ms内,所以有干扰。
如果测来回,目前也比较难以测量,因为一个无法既做发布者,又做订阅者,需要借助ROS,但是ROS之间的通信也会影响时间。
目前考虑两台机器同时开两个终端,互为发送接收,去掉延迟。
结论
目前了解了ZMQ的大致结构以及发布订阅模式的代码编写,发现其丢包问题几乎没有,比较稳定,通信延迟(同一台电脑发布接收)大概6ms,不同电脑之间加上网络延迟目前测试大概在100ms以内,根据不同的网络状况,延迟也许不同,因此该通信协议可以作为最终项目通信协议的选择之一。