[someip专题]vsomeip代码解析2

1someip基础知识

关于SOME/IP的理解_AgingMoon的博客-CSDN博客_someip

2.vsomeip 安装使用

[someip专题]vsomeip使用以及代码解析1_AgingMoon的博客-CSDN博客

3.hello world代码解析

代码下载,大家请参考 ,以下则直接说明每个文件,每个函数,作用,共同记录学习GitHub - COVESA/vsomeip: An implementation of Scalable service-Oriented MiddlewarE over IP

hello world这个案例,主要演示客户端向服务端发送一个请求,服务端接收到请求后,在后面追加一个 "hello",客户端接收到响应后,打印响应的消息 “”hello world“”

3.1 hello_world_client_main.cpp

该文件核心是 创建了一个main的进程,main进程中主要初始化了 一个 hello_world_client的对象,并针对该对象初始化,和运行,那么接下来,核心是查看 hello_world_client这个类做了些啥。

int main(int argc, char **argv)
{
    (void)argc;
    (void)argv;

    hello_world_client hw_cl;
#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
    hw_cl_ptr = &hw_cl;
    signal(SIGINT, handle_signal);
    signal(SIGTERM, handle_signal);
#endif
    if (hw_cl.init()) {
        hw_cl.start();
        return 0;
    } else {
        return 1;
    }
}

3.2 hello_world_client.hpp

文件中构建了一个客户端的类,该客户端的someip 协议信息如下

  • service_id = 0x1111
  • service_instance_id =0x2222
  • service_method_id = 0x3333

构造函数

构造函数中通过vSomeIP协议栈中的runtime,创建了一个应用,针对vSomeIP详细内容,在后续文章中解析,此处我们进一步说明客户端类的做法。

初始化函数

主要做了四件事,应用初始化,注册状态回调函数,注册消息响应回调函数,注册服务可用回调函数。

  • 应用初始化:主要加载启动时指定的配置文件,加载对应的插件库,初始化routing配置
  • 注册状态回调函数:主要用于服务在routing中注册成功后的操作;
  • 注册消息响应回调函数:用于处理从服务端发来的消息响应;
  • 服务可用回调函数:service端在offer server操作成功后,通知client端,最终就调用到了这个函数。

启动函数

启动对应的线程,包括主线程 io线程 maindispatch线程s top_thread线程 Routing线程

状态处理函数

客户端在runtime中被成功注册后,则请求服务;

可用回调函数

客户端识别到 相关服务可用,则会向服务端发送 “”world” 字符串给 服务端

消息回调函数

客户端接收到服务端的响应后,获取接收的消息,并打印 “Received: ”内容,同时结束

结束函数

针对的初始化阶段的操作进行类似于卸载的工作,首先是stop_offer_service,然后unregister我们初始化注册的message_handler和state_handler.

3.3 hello_world_service_main.cpp

和客户端一样,服务端的主函数中,主要申请了一个hello_world_service 对象,同时进行初始化启动。

3.4 hello_world_service.hpp

同样,服务端的类中,也申请了一个someip协议内容相同的类

  • service_id = 0x1111
  • service_instance_id =0x2222
  • service_method_id = 0x3333

构造函数

构造函数也是通过runtime 创建了一个app对象

初始化函数

主要进行应用初始化,注册消息回调,注册状态回调

消息回调函数

接收到客户端的请求后,追加“hello”字符串,并将消息发送给客户端,同时结束应用。

状态回调函数

在runtime注册成功后,服务端开始对外提供服务。

停止函数

主要是等待消息发送后,通知结束,进行服务提供的体制,以及一些反注册操作。

接下来,进一步解析说明使用到的 runtime application 消息的发送和请求,服务的提供和终止等操作。

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 SomeIP 示例代码,用于发送和接收一条消息: ```c++ #include <iostream> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> #define SERVER_IP "127.0.0.1" #define SERVER_PORT 8080 #define SOMEIP_HEADER_LENGTH 12 using namespace std; // SomeIP header结构体 struct SomeIPHeader { uint16_t message_id; uint8_t length; uint8_t protocol_version; uint8_t interface_version; uint8_t message_type; uint8_t return_code; uint8_t flags; uint32_t reserved; }; int main() { int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { cerr << "Failed to create socket." << endl; return -1; } // 构造服务器地址 struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); server_addr.sin_port = htons(SERVER_PORT); // 构造SomeIP消息 SomeIPHeader header; memset(&header, 0, sizeof(header)); header.message_id = htons(0x1234); header.length = 4; header.protocol_version = 1; header.interface_version = 1; header.message_type = 1; header.return_code = 0; header.flags = 0; header.reserved = 0; char message[SOMEIP_HEADER_LENGTH + header.length]; memcpy(message, &header, SOMEIP_HEADER_LENGTH); memcpy(message + SOMEIP_HEADER_LENGTH, "test", header.length); // 发送SomeIP消息 ssize_t send_len = sendto(sock, message, SOMEIP_HEADER_LENGTH + header.length, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (send_len < 0) { cerr << "Failed to send SomeIP message." << endl; close(sock); return -1; } cout << "SomeIP message sent." << endl; // 接收SomeIP消息 char recv_buf[1024]; struct sockaddr_in client_addr; socklen_t client_addr_len = sizeof(client_addr); ssize_t recv_len = recvfrom(sock, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&client_addr, &client_addr_len); if (recv_len < 0) { cerr << "Failed to receive SomeIP message." << endl; close(sock); return -1; } // 解析SomeIP消息 SomeIPHeader *recv_header = (SomeIPHeader *)recv_buf; uint16_t message_id = ntohs(recv_header->message_id); uint8_t length = recv_header->length; char payload[length]; memcpy(payload, recv_buf + SOMEIP_HEADER_LENGTH, length); cout << "SomeIP message received. ID: " << message_id << ", Payload: " << string(payload, length) << endl; close(sock); return 0; } ``` 注意事项: - SomeIP 头部长度为12字节。 - 在发送消息之前,需要构造 SomeIP 消息头部和消息负载。 - 发送和接收消息时,需要指定服务器地址和端口号。 - 接收到的消息需要按照 SomeIP 消息头部指定的长度进行解析

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值