從LCM到SomeIP,再到DDS:技術演進與工作原理剖析

文章目錄

    • 一、LCM:輕量級通信與編組庫
      • 工作原理
      • C++ 代碼示例
      • 局限性
    • 二、SomeIP:面向服務的可擴展中間件
      • 工作原理
      • C++ 代碼示例
      • 優勢與特點
    • 三、DDS:數據分發服務
      • 工作原理
      • C++ 代碼示例
      • 優勢與應用場景
    • 四、技術演進總結

在分布式系統通信領域,技術的革新日新月異,從早期的輕量級通信與編組庫(LCM),到面向服務的可擴展中間件(SomeIP),再到數據分發服務(DDS),每一次的演進都帶來了新的特性與能力提升。接下來,我們將深入探討這三種技術的工作原理,并結合C++ 代碼示例進行說明。

一、LCM:輕量級通信與編組庫

LCM(Lightweight Communications and Marshalling)專為實時系統在高帶寬和低延遲場景下的消息發送與數據封送而設計。它采用發布/訂閱消息模型,特別適用于通過局域網連接的緊密耦合型系統。

工作原理

  1. 發布/訂閱模型:在LCM系統中,數據發布者將特定類型的消息廣播到預配置的多播組。而訂閱者預先聲明對某些類型消息的興趣,當發布者發送消息時,只有訂閱了相應消息類型的訂閱者會接收到該消息。例如,在一個自動駕駛車輛的傳感器數據采集系統中,攝像頭傳感器可以作為發布者,將采集到的圖像數據消息發布到特定的多播組,而負責圖像處理和決策的模塊則作為訂閱者,從該多播組接收圖像數據消息。
  2. 多播機制:LCM復用UDP多播來實現高效的廣播機制。多播允許數據在局域網內一次發送,多個接收者可以同時接收,大大提高了數據傳輸的效率,減少了網絡帶寬的浪費。
  3. 自動封包與解封:LCM提供自動封裝/解封代碼生成工具。開發者只需定義消息的數據結構,LCM就能生成相應語言(如C++ )的代碼,用于將數據結構打包成網絡傳輸的消息以及從接收到的消息中解析出數據結構。

C++ 代碼示例

下面是一個簡單的C++ 示例,展示如何使用LCM發送和接收消息。
首先,定義消息的數據結構:

#include "lcm/lcm-cpp.hpp"
#include <iostream>// 定義一個簡單的消息結構體
struct ExampleMessage {int32_t number;double value;
};
// 為ExampleMessage注冊LCM編碼和解碼函數
LCM_REGISTER_MESSAGE_TYPE(ExampleMessage)

然后是發布者代碼:

int main() {lcm::LCM lcmInstance;if (!lcmInstance.good()) {std::cerr << "LCM initialization error" << std::endl;return 1;}ExampleMessage msg;msg.number = 42;msg.value = 3.14;// 發布消息lcmInstance.publish("EXAMPLE_CHANNEL", &msg);return 0;
}

最后是訂閱者代碼:

class ExampleSubscriber {
public:void handleMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel,const ExampleMessage* msg) {std::cout << "Received on channel " << channel << ": "<< "number = " << msg->number<< ", value = " << msg->value << std::endl;}
};int main() {lcm::LCM lcmInstance;if (!lcmInstance.good()) {std::cerr << "LCM initialization error" << std::endl;return 1;}ExampleSubscriber subscriber;// 訂閱消息lcmInstance.subscribe("EXAMPLE_CHANNEL", &ExampleSubscriber::handleMessage, &subscriber);while (0 == lcmInstance.handle());return 0;
}

在上述代碼中,發布者創建了一個ExampleMessage消息,并通過lcmInstance.publish將其發布到名為EXAMPLE_CHANNEL的通道上。訂閱者則注冊了對EXAMPLE_CHANNEL通道的訂閱,當有消息到達時,會調用handleMessage函數處理消息。

局限性

LCM雖然在實時性和簡單性方面表現出色,但它也存在一些局限性。例如,它主要適用于局域網內的通信,對于廣域網場景支持不足;并且在大規模系統中,多播組的管理和消息的可靠性保障方面存在一定挑戰。

二、SomeIP:面向服務的可擴展中間件

隨著汽車電子等領域的發展,車輛內部網絡變得越來越復雜,需要一種更高效、可擴展且基于服務導向的通信協議,SomeIP應運而生。SomeIP(Scalable service - Oriented MiddlewarE over IP)由AUTOSAR組織定義,旨在通過IP網絡實現車載電子控制單元(ECU)之間的服務化通信。

工作原理

  1. 服務導向模型:SomeIP將車載功能抽象為“服務”。一個服務由服務接口定義,包含方法(客戶端主動調用的功能,如獲取車速)、事件(服務端主動推送的通知,如車速超過閾值)和字段(可讀寫的狀態變量,如當前溫度)。服務通過服務ID唯一標識,其內部元素也有各自的ID進行區分。例如,在汽車的智能駕駛系統中,自動泊車功能可以作為一個服務,其中啟動自動泊車操作可以是一個方法,泊車過程中的狀態變化(如接近障礙物)可以通過事件通知相關模塊。
  2. 服務發現機制:SomeIP - SD(Service Discovery)負責服務的動態發現與管理。服務提供方(Server)通過廣播“Offer Service”消息來廣告自己提供的服務;服務消費方(Client)則通過廣播“Find Service”消息來查詢所需服務。并且采用定時刷新機制來確保服務狀態的時效性,例如Server每T秒(T通常為1 - 10秒,可配置)重發一次“Offer Service”消息,Client在超過一定時間(通常為3 * T)未收到新廣告時,標記服務為“不可用”。
  3. 消息交互:SomeIP定義了多種消息類型,包括請求(Request)、響應(Response)、通知(Notification)等。消息幀由頭部和載荷(payload)組成,頭部包含消息ID(高16位為服務ID,低16位為方法/事件/字段ID + 類型標識)、會話ID(用于關聯請求與響應)等關鍵控制信息;載荷則為業務數據,其格式由應用定義并需遵循序列化規則,例如字節序采用大端(Big - Endian,網絡字節序),對齊方式采用自然對齊以確保不同ECU能正確解析。傳輸層可選擇UDP(低延遲,適合實時數據)或TCP(可靠傳輸,適合關鍵指令)。

C++ 代碼示例

下面是一個簡化的C++ 示例,展示SomeIP服務端和客戶端的基本操作。
首先是服務端代碼,假設定義一個提供獲取車速服務的服務端:

#include <iostream>
// 引入SomeIP相關庫,這里假設庫名為someip_library
#include "someip_library/someip_server.hpp"// 定義獲取車速的方法處理函數
int32_t getSpeedHandler() {// 模擬獲取車速,這里返回一個固定值return 60;
}int main() {someip::Server server;// 注冊服務和方法server.registerService(1234, "SpeedService");server.registerMethod(1234, 5678, "getSpeed", getSpeedHandler);// 啟動服務server.start();while (true);return 0;
}

然后是客戶端代碼,用于調用獲取車速的服務:

#include <iostream>
#include "someip_library/someip_client.hpp"int main() {someip::Client client;// 查找服務client.findService(1234, "SpeedService");// 調用方法獲取車速int32_t speed = client.callMethod<int32_t>(1234, 5678, "getSpeed");std::cout << "Current speed: " << speed << " km/h" << std::endl;return 0;
}

在上述代碼中,服務端通過registerServiceregisterMethod注冊了一個名為“SpeedService”的服務及其“getSpeed”方法,并在啟動后等待客戶端調用。客戶端則通過findService查找服務,然后使用callMethod調用服務的方法獲取車速。

優勢與特點

SomeIP的優勢在于其可擴展性,能夠適應不同規模的車載網絡。它以服務為導向的設計使得車載系統的功能劃分更加清晰,易于維護和升級。同時,服務發現機制解決了車載網絡中ECU啟動順序不確定和服務動態上下線的問題。然而,SomeIP本身未定義安全機制,在安全性要求較高的場景下,需要額外的安全措施,如后續提出的SomeIP - Sec(Secure SOME/IP)來保障通信安全。

三、DDS:數據分發服務

DDS(Data Distribution Service)是對象管理組織(OMG)定義的標準,旨在為分布式實時系統提供高性能、可擴展的數據分發服務。它在工業自動化、航空航天、智能交通等領域得到廣泛應用。

工作原理

  1. 數據中心發布/訂閱模型:DDS采用數據中心發布/訂閱模型,發布者和訂閱者通過“主題(Topic)”進行數據交互。主題定義了數據的類型和語義,發布者將數據發布到特定主題,訂閱者則訂閱感興趣的主題。與LCM不同的是,DDS具有更強大的發現協議,發布者可以自動發現合適的訂閱者,并且消息只會路由到這些訂閱者,而不是像LCM那樣廣播到預配置的多播組。例如,在一個智能工廠的生產線上,不同的傳感器可以將各自采集的數據(如溫度、壓力等)發布到對應的主題,而負責數據分析和控制的系統則訂閱相關主題獲取數據。
  2. 服務質量(QoS)策略:DDS提供豐富的QoS策略,允許用戶根據應用需求定制數據傳輸的特性。例如,可靠性策略可以選擇可靠傳輸(確保數據不丟失)或盡力而為傳輸(適合對實時性要求極高但能容忍少量數據丟失的場景);持久性策略可以決定當訂閱者離線時,發布者的數據是否保存并在訂閱者重新上線時補發;截止期限策略可以規定數據必須在多長時間內送達訂閱者等。
  3. 數據表示與傳輸:DDS支持多種數據表示格式,并且對數據進行高效的序列化和反序列化,以減少網絡傳輸的開銷。同時,它能夠在不同的網絡協議(如UDP、TCP等)上運行,適應不同的網絡環境。

C++ 代碼示例

下面是一個簡單的C++ 示例,展示DDS的發布者和訂閱者操作。假設使用的是一個開源的DDS庫(這里假設庫名為open_dds)。
發布者代碼:

#include <iostream>
#include "open_dds/dds/pub/ddspub.hpp"
#include "open_dds/dds/core/ddscore.hpp"// 定義數據結構
struct SensorData {double temperature;double pressure;
};// 注冊數據類型
DDS_REGISTER_TYPE(SensorData)int main() {dds::domain::DomainParticipant participant(0);dds::topic::Topic<SensorData> topic(participant, "SensorDataTopic");dds::pub::Publisher publisher(participant);dds::pub::DataWriter<SensorData> writer(publisher, topic);SensorData data;data.temperature = 25.5;data.pressure = 1013.25;// 發布數據writer.write(data);return 0;
}

訂閱者代碼:

#include <iostream>
#include "open_dds/dds/sub/ddssub.hpp"
#include "open_dds/dds/core/ddscore.hpp"struct SensorData {double temperature;double pressure;
};DDS_REGISTER_TYPE(SensorData)int main() {dds::domain::DomainParticipant participant(0);dds::topic::Topic<SensorData> topic(participant, "SensorDataTopic");dds::sub::Subscriber subscriber(participant);dds::sub::DataReader<SensorData> reader(subscriber, topic);SensorData data;// 接收數據dds::sub::LoanedSamples<SensorData> samples = reader.take();for (const auto& sample : samples) {if (sample.info().valid()) {data = sample.data();std::cout << "Received: Temperature = " << data.temperature<< ", Pressure = " << data.pressure << std::endl;}}return 0;
}

在上述代碼中,發布者創建了一個SensorData類型的數據,并通過writer.write將其發布到名為“SensorDataTopic”的主題上。訂閱者則從該主題接收數據,通過reader.take獲取數據樣本并進行處理。

優勢與應用場景

DDS的優勢在于其高度的靈活性和可定制性,通過豐富的QoS策略能夠滿足各種復雜實時應用的需求。在航空航天領域,飛機的飛行控制系統需要實時、可靠地獲取各種傳感器數據,DDS的可靠傳輸和低延遲特性能夠保障飛行安全;在智能交通系統中,車輛之間以及車輛與基礎設施之間的通信對實時性和數據準確性要求極高,DDS的高效數據分發和QoS策略可以確保交通信息的及時傳遞和處理。

四、技術演進總結

從LCM到SomeIP,再到DDS,我們可以看到分布式系統通信技術在不斷演進。LCM作為輕量級的通信庫,為實時系統提供了基本的發布/訂閱通信能力,但其應用場景相對局限于局域網內的緊密耦合系統。SomeIP則是為了解決車載網絡等特定領域的通信需求而誕生,以服務導向的設計和服務發現機制適應了復雜車載網絡中功能的抽象與管理,但在安全機制方面存在不足。DDS則更加通用和強大,通過數據中心發布/訂閱模型和豐富的QoS策略,能夠滿足各種復雜實時應用在不同網絡環境下的通信需求,在工業、交通、航空航天等多個領域展現出巨大的優勢。隨著技術的不斷發展,未來分布式系統通信技術有望在性能、安全性、可擴展性等方面取得更大的突破,為更多創新應用提供堅實的基礎。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91987.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91987.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91987.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis里面什么是sdshdr,可以詳細介紹一下嗎?

文章目錄為什么 Redis 不直接使用 C 語言的字符串&#xff1f;sdshdr 的結構sdshdr 的不同類型sdshdr 帶來的優勢總結我們來詳細解析一下 Redis 的核心數據結構之一&#xff1a; sdshdr。sdshdr 是 “Simple Dynamic String header” 的縮寫&#xff0c;意為“簡單動態字符串頭…

RocketMq如何保證消息的順序性

文章目錄1.順序消息的全流程1.1 發送階段&#xff1a;消息分區1.2.存儲階段&#xff1a;順序寫入1.3.消費階段&#xff1a;串行消費2.第三把鎖有什么用?3.順序消費存在的問題和Kafka只支持同一個Partition內消息的順序性一樣&#xff0c;RocketMQ中也提供了基于隊列(分區)的順…

zabbix平臺無法刪除已停用主機的處理案例

在zabbix平臺上刪除已停用的主機&#xff0c;提示“SQL描述式執行已失敗: "DELETE FROM items WHERE (itemid IN &#xff08;.....)”&#xff0c;無法刪除&#xff0c;本文為處理情況。一、問題現象在zabbix平臺上刪除已停用的主機&#xff0c;提示“SQL描述式執行已失敗…

【計算機網絡】6應用層

1.網絡應用模型 特性 客戶/服務器模型(Client-Server, C/S) 對等模型(Peer-to-Peer, P2P) 中心化 是(依賴服務器) 否(去中心化) 角色特點 服務器 客戶機 無中心服務器 提供計算服務 請求計算服務 每個節點(Peer)既是客戶機也是服務器 永久在線 間歇接入網絡 節點間…

基于 Spring Boot + Vue 實現人臉采集功能全流程

一、技術棧與依賴引入 后端依賴 (pom.xml) <!-- 百度AI SDK --> <dependency><groupId>com.baidu.aip</groupId><artifactId>java-sdk</artifactId><version>4.16.19</version><exclusions><exclusion><grou…

《Python基礎》第3期:使用PyCharm編寫Hello World

我們寫文檔大多用 Word、寫表格大多用 Excel、寫幻燈片大多用 PPT。 寫代碼也需要一個軟件作為編輯器&#xff08;傳說的大神用記事本寫代碼純屬玩笑了&#xff0c;越是大神越追求效率&#xff0c;用的軟件功能越強&#xff09;。 Python 現在已經有了非常多的代碼編輯器&#…

我的第一個開源項目:排序算法的多種實現方式

以 排序算法 為例&#xff0c;展示如何在 Python 中進行不同實現方式的對比項目概述本項目旨在通過 Python 實現幾種經典的排序算法&#xff0c;并通過性能對比、代碼注釋和優化手段&#xff0c;為開源社區提供參考。選擇排序、冒泡排序、快速排序和歸并排序作為主要算法&#…

5G-LEO - 用于 5g satellite 鏈接的 OpenAirInterface? 擴展

目標&#xff1a;5G-LEO 旨在加速 OAI 作為開源工具的發展&#xff0c;允許衛星通信社區交流和比較 5G NTN 結果&#xff0c;并促進研發活動的合作。擴展的OAI軟件庫被視為開發早期原型的重要工具&#xff0c;用于驗證關鍵的5G NTN設計方面&#xff0c;并為3GPP標準化過程提供及…

基于 Mybatis 框架*的完整開發流程與順序

基于 MyBatis 框架 的完整開發流程與順序一、環境準備階段1. 新建 Maven 項目&#xff08;或普通 Java 項目&#xff09;作用&#xff1a;用 Maven 統一管理依賴&#xff0c;自動下載 MyBatis、MySQL 驅動等 Jar 包操作&#xff1a;IDE&#xff08;如 IDEA&#xff09;選 Maven…

機械學習--決策樹(實戰案例)

決策樹分兩種分類和回歸&#xff0c;這篇博客我將對兩種方法進行實戰講解一、分類決策樹代碼的核心任務是預測 “電信客戶流失狀態”&#xff0c;這是一個典型的分類任務數據集附在該博客上&#xff0c;可以直接下載代碼整體結構整理代碼主要分為以下幾個部分&#xff1a;導入必…

SQL154 插入記錄(一)

描述牛客后臺會記錄每個用戶的試卷作答記錄到exam_record表&#xff0c;現在有兩個用戶的作答記錄詳情如下&#xff1a;用戶1001在2021年9月1日晚上10點11分12秒開始作答試卷9001&#xff0c;并在50分鐘后提交&#xff0c;得了90分&#xff1b;用戶1002在2021年9月4日上午7點1分…

BeanFactory 和 ApplicationContext 的區別?

口語化答案好的&#xff0c;面試官。BeanFactory和ApplicationContext都是用于管理Bean的容器接口。BeanFactory功能相對簡單。提供了Bean的創建、獲取和管理功能。默認采用延遲初始化&#xff0c;只有在第一次訪問Bean時才會創建該Bean。因為功能較為基礎&#xff0c;BeanFact…

VNC連接VirtualBox中的Ubuntu24.04 desktop圖形化(GUI)界面

測試環境&#xff1a;VirtualBox 7,Ubuntu24.04 desktop,Ubuntu24.04 server(no desktop) 一、下載和安裝dRealVNC viewer。 二、配置 VirtualBox 網絡&#xff1a;NAT 模式 端口轉發 1、打開 VirtualBox&#xff0c;選擇您的 Ubuntu 虛擬機&#xff0c;點擊 設置。 選擇 網…

浮動路由和BFD配置

拓撲圖 前期的拓撲圖沒有交換機配置步驟 1、配置IP地址 終端IP地址的配置 路由器IP地址的配置 配置router的對應接口的IP地址 <Huawei>sys [Huawei]sysname router [router]interface Ethernet 0/0/0 [router-Ethernet0/0/0]ip address 192.168.10.254 24 [router-Ethern…

Docker 實戰 -- Nextcloud

文章目錄前言1. 創建 docker-compose.yml2. 啟動 Nextcloud3. 訪問 Nextcloud4. 配置優化&#xff08;可選&#xff09;使用 PostgreSQL使用 redis添加 Cron 后臺任務5. 常用命令6. 反向代理&#xff08;Nginx/Apache&#xff09;前言 當你迷茫的時候&#xff0c;請點擊 Docke…

【計算機網絡 | 第2篇】計算機網絡概述(下)

文章目錄七.因特網服務提供商&#x1f95d;八.接入網&#x1f95d;主流的家庭寬帶接入方式介入網工作原理&#x1f9d0;DSL技術&#xff1a;銅線上的“三通道”通信DSL的速率標準呈現出顯著的"不對稱"特征&#x1f914;電纜互聯網接入技術&#x1f34b;?&#x1f7e…

SpringMVC 6+源碼分析(四)DispatcherServlet實例化流程 3--(HandlerAdapter初始化)

一、概述 HandlerAdapter 是 Spring MVC 框架中的一個核心組件&#xff0c;它在 DispatcherServlet 和處理程序&#xff08;handler&#xff09;之間扮演適配器的角色。DispatcherServlet 接收到 HTTP 請求后&#xff0c;需要調用對應的 handler 來處理請求&#xff08;如控制器…

【lucene】FastVectorHighlighter案例

下面給出一套可直接拷貝運行的 Lucene 8.5.0 FastVectorHighlighter 完整示例&#xff08;JDK 8&#xff09;&#xff0c;演示從建索引、查詢到高亮的全過程。 > 關鍵點&#xff1a;字段必須 1. 存儲原始內容&#xff08;setStored(true)&#xff09; 2. 開啟 TermVecto…

C++返回值優化(RVO):高效返回對象的藝術

在C開發中&#xff0c;按值返回對象的場景十分常見&#xff08;如運算符重載、工廠函數等&#xff09;&#xff0c;但開發者常因擔憂“構造/析構的性能開銷”而陷入糾結&#xff1a;該不該返回對象&#xff1f;如何避免額外成本&#xff1f;本文將剖析痛點、拆解錯誤思路&#…

用 PyTorch 實現一個簡單的神經網絡:從數據到預測

PyTorch 是目前最流行的深度學習框架之一&#xff0c;以其靈活性和易用性受到開發者的喜愛。本文將帶你從零開始&#xff0c;用 PyTorch 實現一個簡單的神經網絡&#xff0c;用于解決經典的 MNIST 手寫數字分類問題。我們將涵蓋數據準備、模型構建、訓練和預測的完整流程&#…