【一】基於open62541的OPC UA服務器和客戶端


 

OPC UA的好處就不說了,既然你找到了這篇文章,說明你對其已經有了一定的了解。

open62541是在Mozilla Public License v2.0下授權的一個開源的、可跨平台的OPC UA庫,采用C(C99)實現。

open62541的官網地址:https://open62541.org/  github地址:https://github.com/open62541/open62541

在open62541的官網有詳細的幫助文檔,推薦直接查看該文檔,作者也是根據其文檔的幫助實現的基本功能。

在下方可根據需要自行下載相關文件

當然,你也可以去github下載最新文件,自行編譯獲得open62541的.c和.h文件,這是我編譯的詳細過程【零】基於open62541項目編譯單獨的open62541源文件和頭文件

 

環境:Windows 10 home、visual studio 2017 community

所需lib包:WS2_32.Lib

  1. 建立服務器

首先打開VS2017新建一個空項目,然后將open62541.c、open62541.h和WS2_32.Lib分別添加到項目中去,然后新建一個.c或者.cpp文件,主要用於編寫服務器相關的代碼,剛開始可以直接復制open62541提供的參考代碼server,文后附有我所用的server代碼

完成后就可以直接編譯運行了,如下是結果

  2. 建立客戶端

在打開VS2017新建一個空項目,然后將open62541.c、open62541.h和WS2_32.Lib分別添加到項目中去,然后新建一個.c或者.cpp文件,主要用於編寫客戶端相關的代碼,剛開始可以直接復制open62541提供的參考代碼client,完成后如下所示,文后附有我所用的client代碼

直接編譯運行之后會發現終端一閃而過,我們查看服務器的連接信息可以看到如下消息

這意味着我們用代碼建立的客戶端是連接到了服務器的,所以我們在原有的客戶端代碼如下位置加一句話,然后運行就能看到客戶端的信息啦

與服務器代碼進行比較可以發現其值是一樣的

如想較為直觀的感受到建立的服務器,可以下載UaExpert進行查看,官網的需要登錄才能下載,可以直接下我提供的1,2.(安裝軟件>10M,無法一次上傳,分兩次傳的)

 安裝完成之后運行軟件,界面如下所示

點擊途中紅圈添加需要連接的服務器

點擊紅框進行服務器url的配置

1:添加服務器url地址,由ip(或者localhost)+port組成,可以在服務器代碼中查看——必填

2:選擇服務器所用的安全策略——選填

3:填寫與第2步對應的驗證賬戶、密碼或者密匙、證書——根據第2步填寫

4:填寫與服務器建立會話的session名稱——選填

5:之所以放在第5步,是因為如果之前添加過其他的服務時,會沿用上一個的名字,所以可以添加了url之后在修改

如圖是我添加完了之后的界面

之后選中要連接的服務器,連接可以點紅色方框的快捷鍵也可以在服務上右鍵連接

  連接成功之后可以在UaExpert左邊會顯示服務器的數據結構組成;連接成功的同時,在服務器的終端也會打印出連接的通道和會話建立的工程和信息

 現在,把ua-expert左邊的the-answer拖到中間區域查看詳細信息,可以看到其值與服務器代碼里寫的值和代碼客戶端讀出來的值是一樣的。

以上就是在Windows 10下通過visual studio 2017基於open62541建立OPC UA服務器和客戶端的全部過程,如有不懂的可以留言,我看到並且我會的話會回復的。

 

這是根據2019年7月7日【零】基於open62541項目編譯單獨的open62541源文件和頭文件的.c和.h建立的工程文件

server代碼

#include <signal.h>
#include "open62541.h"

UA_Boolean running = true;
void signalHandler(int sig) {
    running = false;
}

int main(int argc, char** argv)
{
    signal(SIGINT, signalHandler); /* catch ctrl-c */

    /* Create a server listening on port 4840 */
    UA_ServerConfig *config = UA_ServerConfig_new_default();
    UA_Server *server = UA_Server_new(config);

    /* Add a variable node */
    /* 1) Define the node attributes */
    UA_VariableAttributes attr = UA_VariableAttributes_default;
    attr.displayName = UA_LOCALIZEDTEXT("en-US", "the answer");
    UA_Int32 myInteger = 42;
    UA_Variant_setScalar(&attr.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);

    /* 2) Define where the node shall be added with which browsename */
    UA_NodeId newNodeId = UA_NODEID_STRING(1, "the.answer");
    UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
    UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
    UA_NodeId variableType = UA_NODEID_NULL; /* take the default variable type */
    UA_QualifiedName browseName = UA_QUALIFIEDNAME(1, "the answer");

    /* 3) Add the node */
    UA_Server_addVariableNode(server, newNodeId, parentNodeId, parentReferenceNodeId,
                              browseName, variableType, attr, NULL, NULL);

    /* Run the server loop */
    UA_StatusCode status = UA_Server_run(server, &running);
    UA_Server_delete(server);
    UA_ServerConfig_delete(config);
    return status;
}

client代碼

#include <stdio.h>
#include "open62541.h"

int main(int argc, char *argv[])
{
    /* Create a client and connect */
    UA_Client *client = UA_Client_new(UA_ClientConfig_default);
    UA_StatusCode status = UA_Client_connect(client, "opc.tcp://localhost:4840");
    if (status != UA_STATUSCODE_GOOD) {
        UA_Client_delete(client);
        return status;
    }

    /* 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);
    status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, "the.answer"), &value);
    if (status == UA_STATUSCODE_GOOD &&
        UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32])) {
        printf("the value is: %i\n", *(UA_Int32*)value.data);
    }

    /* Clean up */
    UA_Variant_deleteMembers(&value);
    UA_Client_delete(client); /* Disconnects the client internally */
    system("pause");
    return status;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM