VSOMEIP双机通信

VSOMEIP双机通信

介绍下demo怎么写的还有双机通信怎么实现



编写配置环境

由于VSOMEIP是个库,所以和其他的库一样用就行了。

首先创建demo目录
在这里插入图片描述这里创建的是vsomeip_demo文件夹

里面创建个server端的cpp和client端的cpp,这里只是编译,不用在两个电脑上分别创建。

建个build,用于存放json配置文件,和CmakeList生成的Makefile等东西。

其中CakeList.txt就是cmake的文件,代码如下:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

set (CMAKE_CXX_FLAGS "-g -std=c++0x")

set (vsomeip_DIR /home/xiong/work/VSOMEIP/source/vsomeip-master)

set (Boost_INCLUDE_DIR /home/xiong/work/VSOMEIP/install/boost_1_72_0/include)

find_package (vsomeip3 REQUIRED)
find_package( Boost 1.72 COMPONENTS system thread log REQUIRED )

include_directories (
    ${Boost_INCLUDE_DIR}
    ${VSOMEIP_INCLUDE_DIRS}
)

add_executable(service service.cpp)
add_executable(client client.cpp)
target_link_libraries(service vsomeip3 ${Boost_LIBRARIES})
target_link_libraries(client vsomeip3 ${Boost_LIBRARIES})

没多少代码,就是添加几个库的路径,添加源文件,能过够让编译器找到对应的库和源文件,这个路径需要改成对应电脑的路径。

然后再build里面编译cmake …
结果如下:
在这里插入图片描述
这里auto.sh和vsoemip.json是为了配置放的,其他都是cmake生成的。

然后make一下:
在这里插入图片描述
然后就生成了server和client两个可执行文件

现在运行./server的话会出现:
在这里插入图片描述
其根本原因是没有库的路径到指定环境变量LD_LIBRARY_PATH中,我又不想永久写到配置文件中,本来想打算写个sh添加以下,后面发现sh好像export不了,没办法只能把sh里面的东西复制出来到终端执行:
在这里插入图片描述
如果想添加到配置文件的话把LD_LIBRARY_PATH添加以下就好了,添加完之后就能正常运行了。

双机通信

双机通信就配置以下vsomeip.json文件就好了,这里我用的是单播进行的通信,这个是server端的,另一台电脑上IP反过来写就行,然后APP的名字和routing名字这些配置改一下就行。

{
    "unicast" : "192.168.0.10",
    "applications" : 
    [
        {
            "name" : "Hello",
            "id" : "0x1313"
        }
    ],
    "routing" : "Hello",
    "service-discovery" :
    {
        "enable" : "true",
        "mode" : "unicast",
        "unicast" : [
            "192.168.0.11"
        ],
        "multicast" : "224.224.224.245",
        "port" : "30490",
        "protocol" : "udp",
        "initial_delay_min" : "10",
        "initial_delay_max" : "100",
        "repetitions_base_delay" : "200",
        "repetitions_max" : "3",
        "ttl" : "3",
        "cyclic_offer_delay" : "2000",
        "request_response_delay" : "1500"
    }
}

配置文件没啥好讲的就是配置以下自己的ip,配置一下app的ID和name,然后配一下SD的参数,设成单播,至于SD报文的重复的base时间这些参数就按照这个设置就行,改不改的不要太离谱就行。

配完make一下生成的两个可执行文件分别放到对应IP的两台主机上进行运行,就可以双机通信了。

代码详解

server.cpp

#include <iomanip>
#include <iostream>
#include <sstream>

#include <vsomeip/vsomeip.hpp>

#define SAMPLE_SERVICE_ID 0x1234
#define SAMPLE_INSTANCE_ID 0x5678
#define SAMPLE_METHOD_ID 0x0421

std::shared_ptr<vsomeip::application> app;

void on_message(const std::shared_ptr<vsomeip::message> &_request) {

	std::cout << "asdfghjkl" << std::endl;
    std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();
    vsomeip::length_t l = its_payload->get_length();

    // Get payload
    std::stringstream ss;
    for (vsomeip::length_t i=0; i<l; i++) {
       ss << std::setw(2) << std::setfill('0') << std::hex
          << (int)*(its_payload->get_data()+i) << " ";
    }

    std::cout << "SERVICE: Received message with Client/Session ["
        << std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
        << std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "] "
        << ss.str() << std::endl;

    // Create response
    std::shared_ptr<vsomeip::message> its_response = vsomeip::runtime::get()->create_response(_request);
    its_payload = vsomeip::runtime::get()->create_payload();
    std::vector<vsomeip::byte_t> its_payload_data;
    for (int i=9; i>=0; i--) {
        its_payload_data.push_back(i % 256);
    }
    its_payload->set_data(its_payload_data);
    its_response->set_payload(its_payload);
    app->send(its_response);
}

int main() {

   app = vsomeip::runtime::get()->create_application("World");
   app->init();
   app->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, on_message);
   app->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
   app->start();
}

没有helloworld那么麻烦,在主函数里面就是注册了一个app,然后init一下,注册一个收到request的回调函数on_message,然后就offer_service跟start,就开启各种线程服务启动了。

client.cpp

#include <iomanip>
#include <iostream>
#include <sstream>

#include <condition_variable>
#include <thread>

#include <vsomeip/vsomeip.hpp>

#define SAMPLE_SERVICE_ID 0x1234
#define SAMPLE_INSTANCE_ID 0x5678
#define SAMPLE_METHOD_ID 0x0421

std::shared_ptr< vsomeip::application > app;
std::mutex mutex;
std::condition_variable condition;

void run() {
  std::unique_lock<std::mutex> its_lock(mutex);
  condition.wait(its_lock);

  std::shared_ptr< vsomeip::message > request;
  request = vsomeip::runtime::get()->create_request();
  request->set_service(SAMPLE_SERVICE_ID);
  request->set_instance(SAMPLE_INSTANCE_ID);
  request->set_method(SAMPLE_METHOD_ID);

  std::shared_ptr< vsomeip::payload > its_payload = vsomeip::runtime::get()->create_payload();
  std::vector< vsomeip::byte_t > its_payload_data;
  for (vsomeip::byte_t i=0; i<10; i++) {
      its_payload_data.push_back(i % 256);
  }
  its_payload->set_data(its_payload_data);
  request->set_payload(its_payload);
  app->send(request);
}

void on_message(const std::shared_ptr<vsomeip::message> &_response) {

  std::cout << "sdsdsdsdsdsdsdsdsdsds" << std::endl;
  std::shared_ptr<vsomeip::payload> its_payload = _response->get_payload();
  vsomeip::length_t l = its_payload->get_length();

  // Get payload
  std::stringstream ss;
  for (vsomeip::length_t i=0; i<l; i++) {
     ss << std::setw(2) << std::setfill('0') << std::hex
        << (int)*(its_payload->get_data()+i) << " ";
  }

  std::cout << "CLIENT: Received message with Client/Session ["
      << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() << "/"
      << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() << "] "
      << ss.str() << std::endl;
}

void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) {
    std::cout << "CLIENT: Service ["
            << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance
            << "] is "
            << (_is_available ? "available." : "NOT available.")
            << std::endl;
    condition.notify_one();
}

int main() {

    app = vsomeip::runtime::get()->create_application("Hello");
    app->init();
    app->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, on_availability);
    app->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
    app->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, on_message);
    std::thread sender(run);
    app->start();
}

client.cpp流程大体和server端一样,就是多注册了几个函数用于request服务,检测服务是否可用等函数,然后开了个线程来发送request数据,最后start,实现一个SOMEIP中最简单的request/response交互流程,有时间的可以抓包看一下报文。

总结

最近出差多没时间总结,现在把之前双机通信的案例总结一下,后面关于多播的就不写了都是一样的。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值