标题DDS程序实现和运行
本文记录了Windows10环境下OpenDDS环境搭建,idl自定义,代码生成,代码编写的全过程。
一、环境搭建
1.详细情况请参考开发笔记:1. OpenDDS环境搭建-Windows 10.note
编译好后生成了两个文件夹“OpenDDS-3.14”,“ACE_wrappers”这两个文件夹就是本地的运行库了。
2.部署两台计算机。
a)把上述的两目录文件拷贝过去,
b)确保两台电脑有同样的开发环境.和设置同样的环境变量.同样的路径.
设置环境变量
1)系统变量
ACE_ROOT F:\J18-ZaiJian\ACE_wrappers
MPC_ROOT F:\J18-ZaiJian\ACE_wrappers\MPC
TAO_ROOT %ACE_ROOT%\TAO
DDS_ROOT F:\J18-ZaiJian\OpenDDS-3.14
2)Path变量
在Path中添加:中添加:
%ACE_ROOT%\lib
%ACE_ROOT%\bin
%DDS_ROOT%\lib
%DDS_ROOT%\bin
二、生成相关代码
0.新建工程目录名称:ZJ-DDS-220301
目录地址:F:\J18-ZaiJian\ZJ-DDS-220301
以下操作全部是在此工程路径下进行的,F:\J18-ZaiJian\ZJ-DDS-220301
1.右键点击新建txt文件,名称为Demo.idl。
编写Demo.idl内容如下:
module DemoIdlModule {
@topic
struct DemoTopic1 {
@key long id;
long counter;
string text;
};
};
2.右键点击新建txt文件,名称为Demo.mpc文件,
将其与Demo.idl放置在一个文件夹,Demo.mpc文件内容如下:
project(*idl): dcps {
TypeSupport_Files {
Demo.idl
}
custom_only = 1
}
project(*publisher) : dcpsexe_with_tcp {
exename = publisher
after += *idl
TypeSupport_Files {
Demo.idl
}
Source_Files {
Publisher.cpp
}
}
project(*subscriber) : dcpsexe_with_tcp {
exename = subscriber
after += *publisher
TypeSupport_Files {
Demo.idl
}
Source_Files {
Subscriber.cpp
DataReaderListener.cpp
}
}
3.右键点击新建txt文件,名称分别为:Publisher.cpp,Subscriber.cpp及DataReaderListener.h/DataReaderListener.cpp
4.使用vs开发人员命令行工具,输入命令:
1)切到Demo.idl及Demo.mpc文件所在目录;
cd F:\J18-ZaiJian\ZJ-DDS-220301
perl %ACE_ROOT%\MPC\mwc.pl -type vs2017
//曾经我用的是这个命令,效果一样:
perl %ACE_ROOT%\MPC\mwc.pl -type vs2017 -include %DDS_ROOT%\MPC\config
2)代码生成完毕后,文件如下图:
3)双击ZJ_DDS_220301.sln,用vs2017打开如下:
5.右键单击解决方案,选择“重新生成解决方案”,查看是否能编译通过。
vs解决方案以及文件夹生成的文件如下:
6.单独为工程编写一个配置文件config_Pub.ini和config_Sub.ini
用于对OpenDDS的协议,功能进行配置,config_Pub.ini和config_Sub.ini,如下:
[common]
DCPSGlobalTransportConfig=$file
DCPSDefaultDiscovery=DEFAULT_RTPS
[transport/the_rtps_transport]
transport_type=rtps_udp
三、编写代码
● 发布端:从本地文件AAA.txt读取数据,作为DDS主题数据,发布出去。
● 订阅端:接收到主题数据后,将数据写入本地文件BBB.txt中。
1. Publisher.cpp
#include <dds/DCPS/Service_Participant.h>
#include <dds/DCPS/Marked_Default_Qos.h>
#include <dds/DCPS/PublisherImpl.h>
#include <dds/DCPS/transport/tcp/TcpInst.h>
#include "dds/DCPS/StaticIncludes.h"
#include <ace/streams.h>
#include "DemoTypeSupportImpl.h"
using namespace DemoIdlModule;
int ACE_TMAIN(int argc, ACE_TCHAR* argv[]) {
try {
// 初始化参与者
argv[1] = "-DCPSConfigFile";
argv[2] = "config_Pub.ini";
argc = 3;
#if 1 //0. 文件 //将参数从文件读出,然后作为DDS传输的主题数据。
FILE* fp;
//char c[] = "The counter is: 5";
char c[] = "2";
char buffer[50] = { 0 };
// char* buffer = { 0 };
// int bufsize = 0;
long _counter = 0; //用来交给6.公布数据的 message.counter
char fname[80] = "F:\\J18-ZaiJian\\AAA.txt";
int charCount = 0;/** 保存文件的字符个数 **/
/* 打开文件用于读 */
if ((fp = fopen(fname, "r")) == NULL)
{
printf("Open file failed!!\n");
exit(1);
}
while (fgetc(fp) != EOF) /** 统计字符个数 **/
charCount++;
/* 查找文件的开头 */
fseek(fp, 0, SEEK_SET);
/* 读取并显示数据 */
// fread(buffer, strlen(buffer) + 1, 1, fp);
fread(buffer, charCount+1, 1, fp);
cout << buffer << endl;
fclose(fp);
/* 字符串转换long */
_counter = strtol(buffer, NULL, 10);
cout << "Begin!!! _counter: " << _counter << endl;
#endif
// 1. 初始化参与者
DDS::DomainParticipantFactory_var dpf =
TheParticipantFactoryWithArgs(argc, argv);
DDS::DomainParticipant_var participant =
dpf->create_participant(111,
PARTICIPANT_QOS_DEFAULT,
DDS::DomainParticipantListener::_nil(),
::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
if (CORBA::is_nil(participant.in())) {
cerr << "create_participant failed." << endl;
return 1;
}
// 2. 注册数据类型
//这里是Topic而不是Topics,意义不同,体现在idl文件里。
DemoTopic1TypeSupportImpl* servant = new DemoTopic1TypeSupportImpl();//这句是要根据XXXXTypeSupportImpl中的前缀与idl文件中的Topic key名对应,在这里即"DemoTopic1"
OpenDDS::DCPS::LocalObject_var safe_servant = servant;
if (DDS::RETCODE_OK != servant->register_type(participant.in(), "")) {
cerr << "register_type failed." << endl;
exit(1);
}
// 3. 创建主题
CORBA::String_var type_name = servant->get_type_name();
DDS::TopicQos topic_qos;
participant->get_default_topic_qos(topic_qos);
DDS::Topic_var topic =
participant->create_topic("Movie Discussion List",
type_name.in(),
topic_qos,
DDS::TopicListener::_nil(),
::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
if (CORBA::is_nil(topic.in())) {
cerr << "create_topic failed." << endl;
exit(1);
}
// 4. 创建公布者
DDS::Publisher_var pub =
participant->create_publisher(PUBLISHER_QOS_DEFAULT,
DDS::PublisherListener::_nil(),
::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
if (CORBA::is_nil(pub.in())) {
cerr << "create_publisher failed." << endl;
exit(1);
}
// 5. 创建数据写者
DDS::DataWriterQos dw_qos;
pub->get_default_datawriter_qos(dw_qos);
DDS::DataWriter_var dw =
pub->create_datawriter(topic.in(),
dw_qos,
DDS::DataWriterListener::_nil(),
::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
if (CORBA::is_nil(dw.in())) {
cerr << "create_datawriter failed." << endl;
exit(1);
}
DemoTopic1DataWriter_var message_dw //这句是要根据XXXXDataWriter_var,XXXXDataWriter中的前缀与idl文件中的Topic key名对应,在这里即"DemoTopic1"
= DemoTopic1DataWriter::_narrow(dw.in());
//
// Get default Publisher QoS from a DomainParticipant:
DDS::PublisherQos pub_qos;
DDS::ReturnCode_t ret;
ret = participant->get_default_publisher_qos(pub_qos);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default publisher QoS" << std::endl;
}
// Get default Subscriber QoS from a DomainParticipant:
DDS::SubscriberQos sub_qos;
ret = participant->get_default_subscriber_qos(sub_qos);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default subscriber QoS" << std::endl;
}
// Get default Topic QoS from a DomainParticipant:
DDS::TopicQos topic_qos2;
ret = participant->get_default_topic_qos(topic_qos2);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default topic QoS" << std::endl;
}
// Get default DomainParticipant QoS from a DomainParticipantFactory:
DDS::DomainParticipantQos dp_qos;
ret = dpf->get_default_participant_qos(dp_qos);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default participant QoS" << std::endl;
}
// Get default DataWriter QoS from a Publisher:
DDS::DataWriterQos dw_qos2;
ret = pub->get_default_datawriter_qos(dw_qos2);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default data writer QoS" << std::endl;
}
// 6. 公布数据
DemoTopic1 message;//这句是要根据idl文件中的Topic key名对应,在这里即"DemoTopic1"
message.id = 99;
::DDS::InstanceHandle_t handle = message_dw->register_instance(message);
// message.counter = 0;
#if 1
message.counter = _counter;
cout << " RETT-message!!!: " << message.counter << endl;
#endif
char tMsg[50] = { 0 };
while (1)
{
message.counter++;
memset(tMsg, 0, 50);
sprintf(tMsg, "RETT-Msg Counter : %d", message.counter);
message.text = ::TAO::String_Manager(tMsg);
message_dw->write(message, handle);
ACE_OS::sleep(1);
cout << "RETT..." << endl;
cout << "RETT-halo eyeryone!!!" << message.counter << endl;
}
// 7. 实体清理
participant->delete_contained_entities();
dpf->delete_participant(participant);
TheServiceParticipant->shutdown();
}
catch (CORBA::Exception& e)
{
cerr << "PUB: Exception caught in main.cpp:" << endl
<< e << endl;
exit(1);
}
return 0;
}
2. Subscriber.cpp
/* 1. 初始化参与者
2. 注册数据类型并创建主题
3. 创建订阅者
4. 创建监听者
5. 创建数据读者
6. 清理与OpenDDS相关联的资源*/
#include "DemoTypeSupportImpl.h"
#include <dds/DCPS/Service_Participant.h>
#include <dds/DCPS/Marked_Default_Qos.h>
#include <dds/DCPS/PublisherImpl.h>
#include <dds/DCPS/transport/tcp/TcpInst.h>
#include "dds/DCPS/StaticIncludes.h"
#include <ace/streams.h>
#include "DataReaderListener.h"
using namespace DemoIdlModule;
int ACE_TMAIN(int argc, ACE_TCHAR* argv[]) {
try
{
// 初始化参与者
argv[1] = "-DCPSConfigFile";
argv[2] = "config_Sub.ini";
argc = 3;
// 1. 初始化参与者
DDS::DomainParticipantFactory_var dpf =
TheParticipantFactoryWithArgs(argc, argv);
DDS::DomainParticipant_var participant =
dpf->create_participant(111,
PARTICIPANT_QOS_DEFAULT,
DDS::DomainParticipantListener::_nil(),
::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
if (CORBA::is_nil(participant.in())) {
cerr << "create_participant failed." << endl;
return 1;
}
// 2. 注册数据类型并创建主题
DemoTopic1TypeSupportImpl* servant = new DemoTopic1TypeSupportImpl();
OpenDDS::DCPS::LocalObject_var safe_servant = servant;
if (DDS::RETCODE_OK != servant->register_type(participant.in(), "")) {
cerr << "register_type failed." << endl;
exit(1);
}
CORBA::String_var type_name = servant->get_type_name();
DDS::TopicQos topic_qos;
participant->get_default_topic_qos(topic_qos);
DDS::Topic_var topic =
participant->create_topic("Movie Discussion List",
type_name.in(),
topic_qos,
DDS::TopicListener::_nil(),
::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
if (CORBA::is_nil(topic.in())) {
cerr << "create_topic failed." << endl;
exit(1);
}
// 3. 创建订阅者
DDS::Subscriber_var sub =
participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT,
DDS::SubscriberListener::_nil(),
::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
if (CORBA::is_nil(sub.in())) {
cerr << "Failed to create_subscriber." << endl;
exit(1);
}
// 4. 创建监听者
DDS::DataReaderListener_var listener(new DataReaderListener);
DataReaderListener* listener_servant =
dynamic_cast<DataReaderListener*>(listener.in());
if (CORBA::is_nil(listener.in())) {
cerr << "listener is nil." << endl;
exit(1);
}
if (!listener_servant) {
ACE_ERROR_RETURN((LM_ERROR,
ACE_TEXT("%N:%l main()")
ACE_TEXT(" ERROR: listener_servant is nil (dynamic_cast failed)!\n")), -1);
}
// 5. 创建数据读者
DDS::DataReaderQos dr_qos;
sub->get_default_datareader_qos(dr_qos);
DDS::DataReader_var dr = sub->create_datareader(topic.in(),
dr_qos,
listener.in(),
::OpenDDS::DCPS::DEFAULT_STATUS_MASK);
if (CORBA::is_nil(dr.in())) {
cerr << "create_datareader failed." << endl;
exit(1);
}
//
// Get default Publisher QoS from a DomainParticipant:
DDS::PublisherQos pub_qos;
DDS::ReturnCode_t ret;
ret = participant->get_default_publisher_qos(pub_qos);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default publisher QoS" << std::endl;
}
// Get default Subscriber QoS from a DomainParticipant:
DDS::SubscriberQos sub_qos;
ret = participant->get_default_subscriber_qos(sub_qos);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default subscriber QoS" << std::endl;
}
// Get default Topic QoS from a DomainParticipant:
DDS::TopicQos topic_qos2;
ret = participant->get_default_topic_qos(topic_qos2);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default topic QoS" << std::endl;
}
// Get default DomainParticipant QoS from a DomainParticipantFactory:
DDS::DomainParticipantQos dp_qos;
ret = dpf->get_default_participant_qos(dp_qos);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default participant QoS" << std::endl;
}
// Get default DataReader QoS from a Subscriber:
DDS::DataReaderQos dr_qos2;
ret = sub->get_default_datareader_qos(dr_qos2);
if (DDS::RETCODE_OK != ret) {
std::cerr << "Could not get default data reader QoS" << std::endl;
}
while (1) {
ACE_OS::sleep(1);
}
// 6. 清理与OpenDDS相关联的资源
participant->delete_contained_entities();
dpf->delete_participant(participant);
TheServiceParticipant->shutdown();
}
catch (CORBA::Exception& e)
{
cerr << "PUB: Exception caught in main.cpp:" << endl
<< e << endl;
exit(1);
}
return 0;
}
3. DataReaderListener.h
// 数据读者监听者实现
#ifndef DATAREADER_LISTENER_IMPL
#define DATAREADER_LISTENER_IMPL
#include <dds/DdsDcpsSubscriptionExtC.h>
#include <dds/DCPS/LocalObject.h>
#if !defined (ACE_LACKS_PRAGMA_ONCE)
#pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
class DataReaderListener
: public virtual OpenDDS::DCPS::LocalObject<OpenDDS::DCPS::DataReaderListener>
{
public:
DataReaderListener();
virtual ~DataReaderListener(void);
virtual void on_requested_deadline_missed(
DDS::DataReader_ptr reader,
const DDS::RequestedDeadlineMissedStatus& status);
virtual void on_requested_incompatible_qos(
DDS::DataReader_ptr reader,
const DDS::RequestedIncompatibleQosStatus& status);
virtual void on_liveliness_changed(
DDS::DataReader_ptr reader,
const DDS::LivelinessChangedStatus& status);
virtual void on_subscription_matched(
DDS::DataReader_ptr reader,
const DDS::SubscriptionMatchedStatus& status);
virtual void on_sample_rejected(
DDS::DataReader_ptr reader,
const DDS::SampleRejectedStatus& status);
virtual void on_data_available(
DDS::DataReader_ptr reader);
virtual void on_sample_lost(
DDS::DataReader_ptr reader,
const DDS::SampleLostStatus& status);
virtual void on_subscription_disconnected(
DDS::DataReader_ptr reader,
const ::OpenDDS::DCPS::SubscriptionDisconnectedStatus& status);
virtual void on_subscription_reconnected(
DDS::DataReader_ptr reader,
const ::OpenDDS::DCPS::SubscriptionReconnectedStatus& status);
virtual void on_subscription_lost(
DDS::DataReader_ptr reader,
const ::OpenDDS::DCPS::SubscriptionLostStatus& status);
virtual void on_budget_exceeded(
DDS::DataReader_ptr reader,
const ::OpenDDS::DCPS::BudgetExceededStatus& status);
long num_reads() const {
return num_reads_;
}
private:
DDS::DataReader_var reader_;
long num_reads_;
};
#endif /* DATAREADER_LISTENER_IMPL */
4. DataReaderListener.cpp
// -*- C++ -*-
//
#include "DataReaderListener.h"
#include "DemoTypeSupportC.h"
#include "DemoTypeSupportImpl.h"
#include <dds/DCPS/Service_Participant.h>
#include <ace/streams.h>
using namespace DemoIdlModule;
DataReaderListener::DataReaderListener()
: num_reads_(0)
{
}
DataReaderListener::~DataReaderListener()
{
}
void DataReaderListener::on_data_available(DDS::DataReader_ptr reader)
{
++num_reads_;
//0. 文件
FILE* fp;
//char c[] = "The counter is: 5";
char c[50] = "2";
char buffer[50] = { 0 };
long _counter = 0;
/* 打开文件用于读写 */
if (fp = fopen("F:\\J18-ZaiJian\\BBB.txt", "w+"))
cout << "RETT-Open file success--- ";
try {
DemoTopic1DataReader_var message_dr = DemoTopic1DataReader::_narrow(reader);
if (CORBA::is_nil(message_dr.in())) {
cerr << "read: _narrow failed." << endl;
exit(1);
}
DemoTopic1 message;
DDS::SampleInfo si;
DDS::ReturnCode_t status = message_dr->take_next_sample(message, si);
if (status == DDS::RETCODE_OK) {
cout << "PP-Message: id = " << message.id << endl
<< " PP-DemoTopic1_Counter = " << message.counter << endl
<< " PP-DemoTopic1_Text = " << message.text << endl;
cout << "SampleInfo.sample_rank = " << si.sample_rank << endl;
_counter = message.counter;
}
else if (status == DDS::RETCODE_NO_DATA) {
cerr << "ERROR: reader received DDS::RETCODE_NO_DATA!" << endl;
}
else {
cerr << "ERROR: read Message: Error: " << status << endl;
}
}
catch (CORBA::Exception& e) {
cerr << "Exception caught in read:" << endl << e << endl;
exit(1);
}
ltoa(_counter, c, 10);
/* 写入数据到文件 */
fwrite(c, strlen(c) + 1, 1, fp);
/* 查找文件的开头 */
fseek(fp, 0, SEEK_SET);
/* 读取并显示数据 */
fread(buffer, strlen(c) + 1, 1, fp);
cout << buffer << endl;
fclose(fp);
}
void DataReaderListener::on_requested_deadline_missed(
DDS::DataReader_ptr,
const DDS::RequestedDeadlineMissedStatus&)
{
cerr << "DataReaderListener::on_requested_deadline_missed" << endl;
}
void DataReaderListener::on_requested_incompatible_qos(
DDS::DataReader_ptr,
const DDS::RequestedIncompatibleQosStatus&)
{
cerr << "DataReaderListener::on_requested_incompatible_qos" << endl;
}
void DataReaderListener::on_liveliness_changed(
DDS::DataReader_ptr,
const DDS::LivelinessChangedStatus&)
{
cerr << "DataReaderListener::on_liveliness_changed" << endl;
}
void DataReaderListener::on_subscription_matched(
DDS::DataReader_ptr,
const DDS::SubscriptionMatchedStatus&)
{
cerr << "DataReaderListener::on_subscription_matched" << endl;
}
void DataReaderListener::on_sample_rejected(
DDS::DataReader_ptr,
const DDS::SampleRejectedStatus&)
{
cerr << "DataReaderListener::on_sample_rejected" << endl;
}
void DataReaderListener::on_sample_lost(
DDS::DataReader_ptr,
const DDS::SampleLostStatus&)
{
cerr << "DataReaderListener::on_sample_lost" << endl;
}
void DataReaderListener::on_subscription_disconnected(
DDS::DataReader_ptr,
const ::OpenDDS::DCPS::SubscriptionDisconnectedStatus&)
{
cerr << "DataReaderListener::on_subscription_disconnected" << endl;
}
void DataReaderListener::on_subscription_reconnected(
DDS::DataReader_ptr,
const ::OpenDDS::DCPS::SubscriptionReconnectedStatus&)
{
cerr << "DataReaderListener::on_subscription_reconnected" << endl;
}
void DataReaderListener::on_subscription_lost(
DDS::DataReader_ptr,
const ::OpenDDS::DCPS::SubscriptionLostStatus&)
{
cerr << "DataReaderListener::on_subscription_lost" << endl;
}
void DataReaderListener::on_budget_exceeded(
DDS::DataReader_ptr,
const ::OpenDDS::DCPS::BudgetExceededStatus&)
{
cerr << "DataReaderListener::on_budget_exceeded" << endl;
}
四、编译
0)点击“重新生成解决方案”,重新编译。
1)编译完成后,生成exe文件如下:
2)在路径下新建文件,名称为:AAA.txt,内容:123
3)把编译好的程序目录拷贝到之前已搭建好同样开发环境的另一台电脑上。
五、运行(1、对等发现方式;2、集中发现方式)
0.运行前准备
操作如下:用网线连接两台电脑。
1)双方电脑安装DUKTO. 然后笔记本电脑将编译成功的工程目录F:\J18-ZaiJian\ZJ-DDS-220301全部拷贝到台式电脑中.
路径地址都是F:\J18-ZaiJian\ZJ-DDS-220301
2)设置IP地址,并确保防火墙全部关闭。必须先确保网络通信没有问题。
3)确保台式电脑的开发环境\环境变量及路径与笔记本电脑的设置是一样的。
配置环境变量和路径的具体步骤请参考文章《OpenDDS环境搭建-Windows 10》.
https://blog.csdn.net/babypphappy/article/details/123228108
1.采用对等发现的方式运行:
config_Pub.ini和config_Sub.ini配置文件内容基本一样为:
[common]
DCPSDefaultDiscovery=DEFAULT_RTPS
DCPSGlobalTransportConfig=$file
[transport/the_rtps_transport]
transport_type=rtps_udp
1).如图:分别在两台电脑上,不分先后的运行一个Publisher或Subscriber实例,
a)一台电脑,执行命令如下:
publisher -DCPSConfigFile config_PubEq.ini
b)另一台电脑,执行命令如下:
subscriber -DCPSConfigFile config_SubEq.ini
c)会看到如下图的运行结果。订阅端会在F:\J18-ZaiJian下生成一个文件:BBB.txt
2). 当然,对等发现方式其实只需要执行./Publisher和./Subscriber,
默认就会去找config_Pub.ini和config_Sub.ini
2. 另外,还有另一种方式,采用集中发现的方式运行:(请查看后面的笔记)
config_Pub.ini和config_Sub.ini配置文件内容基本一样为:
[common]
DCPSDebugLevel=5
DCPSInfoRepo=corbaloc::192.168.2.112:65123/DCPSInfoRepo
DCPSGlobalTransportConfig=config1
[config/config1]
transports=tcp1
[transport/tcp1]
transport_type=tcp
六、具体的集中发现的方式运行(比较繁琐)
操作如下:用网线连接两台电脑。
1)双方电脑安装DUKTO. 然后笔记本电脑将编译成功的工程目录F:\J18-ZaiJian\ZJ-DDS-220301全部拷贝到台式电脑中.
路径地址都是F:\J18-ZaiJian\ZJ-DDS-220301
2)设置IP地址,并确保防火墙全部关闭。必须先确保网络通信没有问题。
3)确保台式电脑的开发环境\环境变量及路径与笔记本电脑的设置是一样的。
配置环境变量和路径的具体步骤请参考文章《OpenDDS环境搭建-Windows 10》.
https://blog.csdn.net/babypphappy/article/details/123228108
A端订阅—台式电脑的操作如下:(确保开发环境\环境变量及路径都设置完毕)
-
台式电脑的IP位:192.168.2.112
ipconfig //查看本机IP地址,确保设置为192.168.2.112, -
打开vs2017开发人员命令行提示符: 看能否ping通笔记本电脑.
ping 192.168.2.110
正在 Ping 192.168.2.110 具有 32 字节的数据:
来自 192.168.2.110 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.2.110 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.2.110 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.2.110 的回复: 字节=32 时间<1ms TTL=64
- 两台电脑互ping能通后,
1)打开vs2017开发人员命令行提示符,先setenv.cmd
%DDS_ROOT%\setenv.cmd
然后开启DCPS服务
%DDS_ROOT%/bin/DCPSInfoRepo -ORBListenEndpoints iiop://192.168.2.112:65123
2)再打开vs2017开发人员命令行提示符,先setenv.cmd
%DDS_ROOT%\setenv.cmd
然后执行:订阅
subscriber -DCPSInfoRepo corbaloc::192.168.2.112:65123/DCPSInfoRepo
B端发布—笔记本电脑的操作如下:(确保开发环境\环境变量及路径都设置完毕)
-
笔记本电脑的IP位:192.168.2.110
ipconfig
//查看笔记本电脑本机IP地址,确保设置为192.168.2.110 -
打开vs2017开发人员命令行提示符: 看能否ping通台式电脑ip
ping 192.168.2.112
正在 Ping 192.168.2.112 具有 32 字节的数据:
来自 192.168.2.112 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.2.112 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.2.112 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.2.112 的回复: 字节=32 时间<1ms TTL=64
-
两台电脑互ping能通成功后,打开vs2017开发人员命令行提示符。
1)先setenv.cmd
%DDS_ROOT%\setenv.cmd
2)然后执行:publisher(发布)
publisher -DCPSInfoRepo corbaloc::192.168.2.112:65123/DCPSInfoRepo
【总结】运行OPenDDS例程(采用集中发现的方式)
(F:\J18-ZaiJian\ZJ-DDS-220301)
两台电脑操作如下运行测试(开发人员命令行提示符:vs2017和vs2019自带的命令行)
☆☆.必须关闭双方所有的防火墙,且确认主机A和主机B能够ping通.☆☆
主机A:(台式电脑 IP:192.168.2.112)[记得提前setenv.cmd]
%DDS_ROOT%/bin/DCPSInfoRepo -ORBListenEndpoints iiop://192.168.2.112:65123
subscriber -DCPSInfoRepo corbaloc::192.168.2.112:65123/DCPSInfoRepo
主机B:(笔记本电脑 IP:192.168.2.110)[记得提前setenv.cmd]
publisher -DCPSInfoRepo corbaloc::192.168.2.112:65123/DCPSInfoRepo