我是 opc 新手,但需要连接服务器。 我的同事告诉我服务器没有安全策略和证书,只有用户名和密码,他对此也不熟悉。
结果是: 在此输入图片描述
我确实通过 UaExpert 与服务器连接: 在此输入图片描述 在此输入图片描述
这是我的代码:
#include "open62541.h"
#include "ros/ros.h"
#include <iostream>
int main() {
UA_Client *client = UA_Client_new();
UA_ClientConfig *cc = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(cc);
cc->securityMode = UA_MESSAGESECURITYMODE_NONE;
const char* serverurl = "opc.tcp://server_ip";
const char* username = "username";
const char* password = "123";
UA_StatusCode retval = UA_Client_connectUsername(client, serverurl, username, password);
if(retval != UA_STATUSCODE_GOOD) {
UA_Client_delete(client);
return EXIT_FAILURE;
}
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Connected!");
UA_Client_disconnect(client);
UA_Client_delete(client);
return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
我找不到解决方案,所以我问这个问题 谢谢
我在一篇博客文章中观察到同样的问题,与我的情况不同,作者开发了自己的服务器。所以他做了一些测试: 在服务器端,当允许匿名和用户名/密码身份验证时,当服务器端点设置为非加密模式(仅具有“无”作为安全性)时,使用任一方法的客户端都可以成功连接。但是,将加密端点添加到服务器配置后,无法通过未加密(“无”)端点通过用户名和密码进行身份验证。
他的结论是: 配置加密安全策略后,服务器默认采用最严格的加密方式,导致客户端尝试使用非加密方式连接失败。
考虑到这些信息,我继续尝试使用加密进行连接。
cc->securityPolicyUri = UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#None");
cc->securityMode = UA_MESSAGESECURITYMODE_NONE;
然后加载客户端生成的证书和私钥,通过用户名和密码验证成功连接到服务器。 此连接不仅允许访问,还允许修改服务器上的数据。
代码是:
bool open62541tool::connect()
{
UA_ByteString certificate = loadFile(cli.certs);
UA_ByteString privateKey = loadFile(cli.keys);
UA_ClientConfig *cc = UA_Client_getConfig(this->client);
cc->securityPolicyUri = UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#None");
cc->securityMode = UA_MESSAGESECURITYMODE_NONE;
UA_ClientConfig_setDefaultEncryption(cc, certificate, privateKey,0,0,0,0);
UA_SecurityPolicy_None(cc->securityPolicies, certificate, &cc->logger);
UA_String_deleteMembers(&cc->clientDescription.applicationUri);
cc->clientDescription.applicationUri = UA_STRING_ALLOC("urn:open62541.client.application");
UA_StatusCode retval = UA_Client_connect_username(this->client, cli.endpointUrl, cli.username, cli.password);
if(retval != UA_STATUSCODE_GOOD) {
return EXIT_FAILURE;
}
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "#############!!!!##Connected################");
UA_ByteString_clear(&certificate);
UA_ByteString_clear(&privateKey);
return true;
}
如果我的回答有任何问题,希望大家提出意见。