學習open62541 --- [79] 在docker中運行open62541工程

docker是非常流行的容器技術,解決了部署環境不一致的問題,open62541的工程也可以在docker容器中運行,本文講述如何把open62541工程放到docker容器中運行。

本文使用WSL ubuntu 22.04作為宿主環境,其它linux也是一樣。


一 拉取debian鏡像

執行docker命令拉取debian鏡像

docker pull debian:bookworm

這個debian鏡像創建的容器非常干凈,啥都沒有,都需要自己安裝,如果我想創建多個容器,那就要安裝多次,所以這里基于debian:bookworm來制作自定義鏡像。


二 編寫Dockerfile

通過Dockerfile來制作自定義鏡像,

# 使用 debian:bookworm 作為基礎鏡像
FROM debian:bookworm# 設置環境變量以避免交互式配置提示
ENV DEBIAN_FRONTEND=noninteractive# 確保 /etc/apt/sources.list 文件存在,并使用國內鏡像源(以阿里云為例)
RUN if [ ! -f "/etc/apt/sources.list" ]; then echo "deb http://mirrors.aliyun.com/debian/ bookworm main non-free contrib" > /etc/apt/sources.list && \echo "deb-src http://mirrors.aliyun.com/debian/ bookworm main non-free contrib" >> /etc/apt/sources.list && \echo "deb http://mirrors.aliyun.com/debian/ bookworm-updates main non-free contrib" >> /etc/apt/sources.list && \echo "deb-src http://mirrors.aliyun.com/debian/ bookworm-updates main non-free contrib" >> /etc/apt/sources.list; fi# 更新包列表并安裝常用開發工具
RUN apt-get update && \apt-get install -y \git \curl \wget \cmake \vim \sudo \build-essential \python3 \python-is-python3 \python3-pip \python3.11-venv \openssh-client \net-tools \iproute2 \iputils-ping \dnsutils \ca-certificates \gnupg \lsb-release \&& apt-get clean \&& rm -rf /var/lib/apt/lists/*# 創建虛擬環境目錄
RUN python3 -m venv /opt/venv# 設置虛擬環境為當前環境
ENV PATH="/opt/venv/bin:$PATH"# 設置容器啟動時默認執行的命令
CMD ["bash"]

然后運行docker命令來制作鏡像,

docker build -t myimage:0.0.1 .

執行完畢后,運行docker images來查看當前的本地鏡像,
![[Pasted image 20250707215627.png]]

這個鏡像可以推送到docker hub或者其他倉庫里,然后分享給別人使用,這樣就保證開發環境是一樣的了。


三 創建open62541工程

在WSL ubuntu下創建一個簡單的open62541工程,工程結構如下,包含server和client
![[Pasted image 20250708210916.png]]

open62541使用的版本是v1.4.12,
client.c內容如下,

// client.c,功能主要是從server那里獲取時間
#include <stdlib.h>
#include "open62541.h"int main(void) 
{UA_Client *client = UA_Client_new();UA_ClientConfig_setDefault(UA_Client_getConfig(client));UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");if(retval != UA_STATUSCODE_GOOD) {UA_Client_delete(client);return (int)retval;}/* Read the value attribute of the node. UA_Client_readValueAttribute is a* wrapper for the raw read service available as UA_Client_Service_read. */UA_Variant value; /* Variants can hold scalar values and arrays of any type */UA_Variant_init(&value);/* NodeId of the variable holding the current time */const UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);retval = UA_Client_readValueAttribute(client, nodeId, &value);if(retval == UA_STATUSCODE_GOOD && UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_DATETIME])) {UA_DateTime raw_date = *(UA_DateTime *) value.data;UA_DateTimeStruct dts = UA_DateTime_toStruct(raw_date);UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "date is: %u-%u-%u %u:%u:%u.%03u\n",dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);}/* Clean up */UA_Variant_clear(&value);UA_Client_delete(client); /* Disconnects the client internally */return EXIT_SUCCESS;
}

server.c內容如下,

// server.c
#include "open62541.h"#include <signal.h>
#include <stdlib.h>UA_Boolean running = true;static void stopHandler(int sign) {UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c");running = false;
}int main(void) 
{signal(SIGINT, stopHandler);signal(SIGTERM, stopHandler);UA_Server *server = UA_Server_new();UA_ServerConfig_setDefault(UA_Server_getConfig(server));UA_StatusCode retval = UA_Server_run(server, &running);UA_Server_delete(server);return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

CMakeLists.txt內容如下,

cmake_minimum_required(VERSION 3.10)project(demo)add_definitions(-std=c99)add_library(open62541 open62541/open62541.copen62541/open62541.h
)add_executable(client src/client.c)
target_include_directories(client PRIVATE open62541)
target_link_libraries(client open62541 pthread)add_executable(server src/server.c)
target_include_directories(server PRIVATE open62541)
target_link_libraries(server open62541 pthread)

最后,在工程根目錄下添加.devcontainer.json,內容如下,

{"image":"myimage:0.0.1"
}

這個用于指導使用哪個鏡像來生成容器。


四 在容器中運行工程

使用VSCode打開工程,然后Ctrl+Shift+p打開命令界面,執行“Dev Containers: Reopen in Container”
![[Pasted image 20250708221118.png]]

這個執行后會通過鏡像創建容器,然后在容器里打開本工程,最后VScode左下角會變成下面這樣,
![[Pasted image 20250709210120.png]]

表示已經在容器里打開了,默認是root用戶。

工程在容器中的目錄是/workspaces/prj_001/

在工程根目錄下創建build目錄,然后cd進入后執行下面命令進行編譯,

cmake .. && make

這里需要創建終端執行命令,有2種方式,

  1. 使用VSCode的終端,因為VSCode已經和容器連接成功了
  2. 在WSL linux下打開終端,然后輸入docker ps來查看容器id,最后執行docker exec -it 容器id bash,就可以進入容器里了

編譯成功后運行server,默認端口是4840,VSCode里會自動轉發,
![[Pasted image 20250709210954.png]]

這樣我們在容器外面使用UaExpert也可以訪問,非常方便,
![[Pasted image 20250709211035.png]]

這里解釋一下為什么使用Reopen in container:因為可以把工程放在宿主機里,如果容器掛了,那么重新開個容器就可以了,如果把工程放到容器里,那么就存在一定的風險了。

還有一點,工程在容器里打開后,里面的文件權限都變成root的了,因為容器默認的用戶就是root,當我們在宿主機里想修改工程文件時,就會提示權限不夠,解決辦法是在工程根目錄下,執行下面的命令,把文件的owner再變回來,

sudo chown -R user_name .

user_name就是宿主機的登錄用戶名。

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

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

相關文章

Spring Boot微服務中集成gRPC實踐經驗分享

Spring Boot微服務中集成gRPC實踐經驗分享 一、業務場景描述 在某電商系統中&#xff0c;推薦服務、庫存服務、訂單服務等微服務需要高效、雙向流式通信&#xff0c;RESTHTTP已無法滿足低延遲、高并發和嚴格類型安全的需求。為此&#xff0c;我們選擇在Spring Boot微服務中集成…

springboot項目編寫測試類,亂碼問題解決

?MockMvc 的默認行為? MockMvc ?默認使用 ISO-8859-1 解碼響應&#xff0c;而服務端實際返回 UTF-8 編碼數據 。 Postman 無亂碼是因瀏覽器自動識別編碼&#xff0c;但 MockMvc 需顯式配置。 ?過濾器失效場景? Spring 的 CharacterEncodingFilter ?默認只對 POST 請求生效…

打破傳統,開啟 AR 智慧課堂?

在教育領域&#xff0c;AR 智慧課堂宛如一場及時雨&#xff0c;為傳統教育模式帶來了革命性的變革&#xff0c;讓學習變得更加生動有趣、高效互動。通過 AR 技術&#xff0c;抽象的知識瞬間變得鮮活起來&#xff0c;學生們可以在虛擬與現實交織的世界中&#xff0c;探索歷史的長…

熱烈祝賀 Flink 2.0 存算分離入選 VLDB 2025

VLDB 2025 論文熱烈祝賀 Apache Flink 2.0 的重磅研究成果《Disaggregated State Management in Apache Flink 2.0 》被數據庫領域頂級會議 VLDB 2025 正式接收&#xff01;這項工作由 Apache Flink 社區 聯合 阿里巴巴實時計算 Flink 團隊 以及多位學術界研究人員共同完成&…

蓄電池能量管理matlab的simulink仿真

蓄電池能量管理matlab的simulink仿真模型 AlternatorTableData.mat , 7395 Battery_Management_Lib.mdl , 577258 Readme.txt , 1293 license.txt , 1551 ssc_battery_management.mdl , 221248 ssc_lead_acid_battery_50Ah_ini.m , 1760 ssc_lead_acid_battery_80Ah_ini.m , 1…

MyBatisPlus-03-擴展功能

文章目錄【README】【1】基于MyBatisPlus的代碼生成器【2】MyBatisPlus-DB靜態工具【2.1】使用MyBatisPlus的DB靜態工具查詢單個及多個用戶地址【查詢單個用戶的訪問效果】【查詢多個用戶的訪問效果】【3】邏輯刪除【3.1】代碼實現【4】枚舉處理器【4.1】代碼實現【5】JSON處理…

初識Neo4j之Cypher(三)

目錄 一、介紹 二、語法 1、節點 2、關系 3、屬性 4、模式 一、介紹 Cypher 是 Neo4j 的聲明式查詢語言&#xff0c;兼容 GQL 標準。通過 openCypher 項目&#xff0c;Cypher 以開源方式提供。它類似于 SQL&#xff0c;但專為圖數據優化。 Cypher 直觀且接近自然語言&…

19-C#靜態方法與靜態類

C#靜態方法與靜態類 1.static-靜態方法animal.eat&#xff08;&#xff09;;//直接調用 public class animal {public static void eat()//定義靜態方法{messagebox.show("animal eat");} }2.static-靜態類animal.eat&#xff08;&#xff09;;//直接調用public stat…

基于YOLO的足球檢測Web應用:從訓練到部署的完整實戰

用Python和深度學習技術打造一個完整的足球檢測系統&#xff0c;支持圖片檢測、視頻分析和實時監控。本文帶你從零開始構建一個專業的Web應用。&#x1f3af; 項目背景 在體育賽事分析和足球訓練中&#xff0c;準確識別和定位足球是一個重要需求。本項目利用YOLO深度學習算法&a…

npm 切換 node 版本 和npm的源

在開發過程中&#xff0c;不同項目可能需要不同版本的 Node.js&#xff0c;同時 于由XX原因&#xff0c;我們需要切換npm的源。這時如果需要切換node版本或者npm的源&#xff0c;我們可以使用以下方法。 使用 nvm 切換 Node 版本 1、安裝 npm install nvm -g2、使用 # 列出所有…

Java學習第二十部分——EasyMock

目錄 一.概述 二.作用 三.工作原理 四.使用示例 五.主要特點 六.適用場景 七.其他模擬框架比較 八.idea簡單項目實戰 1.打開idea創建Java項目&#xff0c;注意構建系統選“Maven” 2.為pom.xml文件添加如下依賴&#xff0c;并重新加載Maven依賴&#xff0c;直至不報錯…

機器學習模型在C++平臺的部署

一、概述機器學習模型的訓練通常在Python環境下完成&#xff0c;而現實生產環境的復雜性和多樣性使得模型的部署成為一個值得關注的重點。不同應用場景下有不同適應的實現方式&#xff0c;這里主要介紹通過一種通用中間格式——ONNX&#xff08;Open Neural Network Exchange&a…

保姆級安裝 Ruby 環境下載及安裝教程, RubyInstaller下載及安裝教程

一、下載安裝 RubyInstaller 1.打開 RubyInstaller 官網&#xff1a;https://rubyinstaller.org/ 點擊跳轉, 官網界面如下圖&#xff1a; 點擊下載最新的 RubyDevkit 版本&#xff08;如 RubyDevkit 3.4.X (x64) &#xff09;。如下圖所示&#xff1a; 注意點&#xff1a;如果…

SQL 一鍵生成 Go Struct!支持字段注釋、類型映射、結構體命名規范

SQL 一鍵生成 Go Struct&#xff01;支持字段注釋、類型映射、結構體命名規范 在 Golang 開發中&#xff0c;尤其是操作數據庫時&#xff0c;我們經常會遇到這種場景&#xff1a; ? 拿到數據庫建表 SQL&#xff0c;卻要手動寫 Go struct? 字段幾十個、類型復雜&#xff0c;…

Web 前端框架選型:React、Vue 和 Angular 的對比與實踐

Web 前端框架選型&#xff1a;React、Vue 和 Angular 的對比與實踐 選擇前端框架就像選擇一個長期合作伙伴。錯誤的選擇可能會讓你的項目在未來幾年內背負沉重的技術債務&#xff0c;而正確的選擇則能讓開發效率飛速提升。 經過多年的項目實踐&#xff0c;我發現很多新人在框架…

C# 值拷貝、引用拷貝、淺拷貝、深拷貝

值拷貝定義&#xff1a;直接復制變量的值&#xff0c;適用于基本數據類型&#xff08;如int, float, char等&#xff09;。在 C# 中&#xff0c;值類型&#xff08;基本數據類型和結構體&#xff09;默認使用值拷貝。特點&#xff1a;創建原始值的完全獨立副本&#xff0c;修改…

深度學習圖像分類數據集—百種鳥類識別分類

該數據集為圖像分類數據集&#xff0c;適用于ResNet、VGG等卷積神經網絡&#xff0c;SENet、CBAM等注意力機制相關算法&#xff0c;Vision Transformer等Transformer相關算法。 數據集信息介紹&#xff1a;525種鳥類識別分類 訓練數據集總共有84635張圖片&#xff0c;每個文件夾…

零基礎 “入坑” Java--- 八、類和對象(一)

文章目錄一、初識面向對象二、類的定義和使用1.認識類2.類的定義格式三、類的實例化四、this引用五、對象的構造及初始化1.有關初始化2.構造方法3.就地初始化一、初識面向對象 Java是一門純面向對象的語言&#xff08;OOP&#xff09;&#xff0c;在面向對象的世界里&#xff…

數字孿生技術引領UI前端設計新篇章:智能物聯網的深度集成

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言&#xff1a;數字孿生與物聯網的共生革命在智能設備爆發式增長的今天&#xff0c;傳統…

代碼審計-shiro漏洞分析

一、關于shiro介紹 簡單講&#xff0c;shiro是apache旗下的一個Java安全框架&#xff0c;輕量級簡單易上手&#xff0c;框架提供很多功能接口&#xff0c;常見的身份認證 、權限認證、會話管理、Remember 記住功能、加密等等。 二、漏洞分析 1.CVE-2019-12422-shiro550 漏洞原理…