学习open62541 --- [37] 与KEPServerEX进行简单通信

KEPServerEX是很有名的OPC Server软件,本文主要讲述如何使用open62541的Client功能来和KEPServerEX进行简单通信。


一 KEPServerEX的安装和使用

本人平时很少使用KEPServerEX,对于KEPServerEX来说是个初学者,也是在网上找资料。可以参考以下两篇:

KEPServerEX运行后会自动创建一个Server,其地址和端口号是opc.tcp://127.0.0.1:49320,使用UaExpert在本机观察如下,
在这里插入图片描述
共有4个endpoint。


二 添加用户

本文的Client使用用户名密码来与KEPServerEX进行连接,相关内容可参考这篇文章

我们在KEPServerEX里添加一个用户,右击下图中的绿色ex图标,选择Settings
在这里插入图片描述
然后选择User Manager,点击添加用户按钮,添加一个用户名字叫hello,密码是123
在这里插入图片描述


三 连接

由上节可以看到通信需要加密,这里使用OpenSSL进行操作,相关内容可参考这篇文章,需要为Client生成证书和私匙。

本文使用VS2015,open62541版本是V1.1.1,Client代码如下,功能就是读取一下Server的系统UTC时间,比较简单,选择的endpoint是Basic256 - Sign & Encrypt

/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
* See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */

#define _CRT_SECURE_NO_WARNINGS

#include <stdlib.h>

#pragma comment(lib,"libssl.lib")
#pragma comment(lib,"libcrypto.lib")
#pragma warning(disable: 4996)      

#include "common.h"


#define MIN_ARGS 4

int main(int argc, char* argv[]) {
    
    
	if (argc < MIN_ARGS) {
    
    
		UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
			"Arguments are missing. The required arguments are "
			"<opc.tcp://host:port> "
			"<client-certificate.der> <client-private-key.der> "
			"[<trustlist1.der>, ...]");
		return EXIT_FAILURE;
	}

	const char *endpointUrl = argv[1];

	/* 加载client的证书和私匙 */
	UA_ByteString certificate = loadFile(argv[2]);
	UA_ByteString privateKey = loadFile(argv[3]);

	/* 加载trustList. revocationList目前还不支持 */
	size_t trustListSize = 0;
	if (argc > MIN_ARGS)
		trustListSize = (size_t)argc - MIN_ARGS;
	UA_STACKARRAY(UA_ByteString, trustList, trustListSize);
	for (size_t trustListCount = 0; trustListCount < trustListSize; trustListCount++)
		trustList[trustListCount] = loadFile(argv[trustListCount + 4]);

	UA_ByteString *revocationList = NULL;
	size_t revocationListSize = 0;

	UA_Client *client = UA_Client_new();
	UA_ClientConfig *cc = UA_Client_getConfig(client);
	cc->securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT;
	cc->securityPolicyUri = UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256");
	UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey,
		trustList, trustListSize,
		revocationList, revocationListSize);

	// 给安全策略None添加证书信息,去除运行时不匹配的警告
	UA_SecurityPolicy_None(cc->securityPolicies, certificate, &cc->logger);

	// 填坑的地方,非常重要,URI需要保证和证书里的URI一致
	cc->clientDescription.applicationUri = UA_STRING_ALLOC("urn:open62541.client.application");

	UA_ByteString_clear(&certificate);
	UA_ByteString_clear(&privateKey);
	for (size_t deleteCount = 0; deleteCount < trustListSize; deleteCount++) {
    
    
		UA_ByteString_clear(&trustList[deleteCount]);
	}

	/* Secure client connect */
	cc->securityMode = UA_MESSAGESECURITYMODE_SIGNANDENCRYPT; /* require encryption */
	UA_StatusCode retval = UA_Client_connect_username(client, endpointUrl, "hello", "123");
	if (retval != UA_STATUSCODE_GOOD) {
    
    
		UA_Client_delete(client);
		return EXIT_FAILURE;
	}

	UA_Variant value;
	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);
	return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

运行命令:

encryp_openssl.exe opc.tcp://127.0.0.1:49320 client_cert.der client_key.der "KEPServerEX_UA Server [A05ECEC2133854A7B9C4CC65EF7F263F9D6E0270].der"

编译成功后,第一次运行时会出现错误,会被KEPServerEX拒绝,因为使用的是自签名证书,不是正式颁发的证书,所以KEPServerEX默认不会信任这个证书。

如何让KEPServerEX信任Client的证书呢?首先右击下图中的绿色ex图标,选择OPC UA Configuration,
在这里插入图片描述
这样就打开了KEPServerEX配置管理器,然后选择Trusted Clients,可以看到Client的证书已经显示在这里了,但是处于被拒绝状态,如下,
在这里插入图片描述
选中这个证书,然后点击下方的Trust,
在这里插入图片描述
这样KEPServerEX就会信任Client的安全证书了。

再次运行Client的执行命令,就能正确获取Server的系统UTC时间了,
在这里插入图片描述


四 如何获取KEPServerEX的证书

看完上一节肯定会问:如何获得KEPServerEX的证书?本人是使用UaExpert获取的,也就是先使用UaExpert进行连接,第一次连接会提示是否信任
在这里插入图片描述
点击Trust Server Certificate和Continue,这样UaExpert就可以获取到Server的安全证书了,
在这里插入图片描述
证书的存放位置可以参考这篇文章

PS:使用UaExpert连接时也可能被拒绝,可以参照上一节的操作,设置为信任。


五 总结

本文主要讲述如何使用open62541的Client功能与KEPServerEX进行简单通信,这是个基础,有了这个基础,后面就可以进行各种操作了。

如果有写的不对的地方,希望能留言指正,谢谢阅读。

猜你喜欢

转载自blog.csdn.net/whahu1989/article/details/108740339
37
今日推荐