OPC UA 빠른 시작
이 페이지에서는 OPC UA SDK 패키지를 풀고, 응용 프로그램 인증서를 만들고, 예제 서버와 C 클라이언트로 첫 보안 연결을 만듭니다. 10분 정도 걸립니다. 명령은 macOS(Apple Silicon) 기준입니다.
준비물
섹션 제목: “준비물”- PDComm OPC UA SDK
native패키지:pdcomm-opcua-native-darwin-arm64.tar.gz. 다른 운영 체제의 패키지 이름은pdcomm-opcua-native-<os>-<arch>형식입니다. - CMake 3.21 이상과 C11·C++17 컴파일러(macOS에서는 Xcode Command Line Tools)
- OpenSSL 3 명령행 도구(예: Homebrew
openssl@3) - 평가판이나 개발 라이선스 파일. 서버와 클라이언트를 실행하는 두 터미널에서
export PDCOMM_LICENSE_FILE="$HOME/pdcomm/pdcomm.license"처럼 경로를 지정합니다. 라이선스 설치와 확인을 참고합니다.
1. 패키지 풀기
섹션 제목: “1. 패키지 풀기”전달받은 SHA-256 값과 패키지 파일의 해시를 비교합니다.
shasum -a 256 pdcomm-opcua-native-darwin-arm64.tar.gz원하는 디렉터리에 패키지를 풀고 SDK 루트로 이동합니다.
tar -xzf pdcomm-opcua-native-darwin-arm64.tar.gzcd pdcomm-opcua-native-darwin-arm64SDK 루트에는 다음 항목이 있습니다.
| 경로 | 내용 |
|---|---|
include/pdcomm/opcua/ |
C 헤더 pdcomm_opcua.h, C++ 헤더 pdcomm_opcua.hpp |
lib/ |
libpdcomm_opcua_ffi.dylib와 OpenSSL 3 런타임 |
examples/opcua/ |
예제 소스, CMake 프로젝트, 인증서 설정 템플릿(pki/*.cnf) |
licenses/, NOTICE.txt |
제3자 라이선스 |
manifest.json |
패키지 종류, ABI 버전, 공개 함수 목록, 모든 파일의 SHA-256 |
SDK 디렉터리는 공백이 있는 경로를 포함해 어디로든 옮길 수 있습니다. 옮긴 뒤에는 예제를 다시 빌드합니다.
2. 응용 프로그램 인증서 만들기
섹션 제목: “2. 응용 프로그램 인증서 만들기”예제 서버는 보안 연결만 받고, 서버와 클라이언트는 상대 인증서 하나만 신뢰합니다. 템플릿으로 서버와 클라이언트의 자체 서명 인증서를 만듭니다.
cd examples/opcua/pkiopenssl req -x509 -new -config server.cnf -newkey rsa:2048 -sha256 -days 365 -noenc \ -keyout server.key.pem -out server.cert.pemopenssl x509 -in server.cert.pem -outform DER -out server.deropenssl req -x509 -new -config client.cnf -newkey rsa:2048 -sha256 -days 365 -noenc \ -keyout client.key.pem -out client.cert.pemopenssl x509 -in client.cert.pem -outform DER -out client.derchmod 600 server.key.pem client.key.pemcd ../../..pki 디렉터리에 인증서(*.cert.pem, *.der)와 개인 키(*.key.pem)가 생깁니다. openssl 명령이 OpenSSL 3이 아니면 /opt/homebrew/opt/openssl@3/bin/openssl처럼 OpenSSL 3의 경로를 씁니다. 템플릿의 의미와 수정 방법은 PKI와 신뢰 설정에서 설명합니다.
3. 예제 빌드
섹션 제목: “3. 예제 빌드”SDK 루트에서 예제를 빌드합니다. 예제는 자신을 포함한 SDK를 자동으로 찾습니다.
cmake -S examples/opcua -B build -DCMAKE_BUILD_TYPE=Releasecmake --build build --config Releasebuild 디렉터리에 opcua_server, opcua_client, opcua_browse_call(C)과 opcua_server_cpp, opcua_client_cpp(C++)가 생깁니다.
4. 서버 실행
섹션 제목: “4. 서버 실행”터미널을 하나 열고 SDK 루트에서 예제 서버를 실행합니다.
build/opcua_server 127.0.0.1:4840 opc.tcp://localhost:4840/pdcomm \ examples/opcua/pki/server.der examples/opcua/pki/server.key.pem examples/opcua/pki/client.der인자는 차례로 수신 주소, 광고할 endpoint URL, 서버 인증서, 서버 개인 키, 신뢰할 클라이언트 인증서입니다. 서버가 준비되면 다음 줄을 출력합니다.
Listening on 127.0.0.1:4840서버는 네임스페이스 2에 변수 세 개를 둡니다.
| NodeId | 이름 | 접근 | 초기값 |
|---|---|---|---|
ns=2;i=1001 |
Value | 익명 포함 공개, 쓰기 가능 Int32 | 42 |
ns=2;i=1002 |
Limit | 공개, 읽기 전용 Int32 | 100 |
ns=2;i=1003 |
Protected | 인증된 사용자 전용 Int32 | 7 |
5. 첫 연결과 읽기
섹션 제목: “5. 첫 연결과 읽기”두 번째 터미널을 열고 SDK 루트에서 클라이언트를 실행합니다.
build/opcua_client opc.tcp://localhost:4840/pdcomm \ examples/opcua/pki/client.der examples/opcua/pki/client.key.pem examples/opcua/pki/server.der인자는 차례로 endpoint URL, 클라이언트 인증서, 클라이언트 개인 키, 신뢰할 서버 인증서입니다. 클라이언트는 엔드포인트 목록을 출력하고, Aes256_Sha256_RsaPss·SignAndEncrypt 보안 채널로 세션을 열어 익명으로 활성화한 뒤 ns=2;i=1001을 읽습니다.
PDComm OPC UA ABI 0x00000002Endpoint opc.tcp://localhost:4840/pdcomm mode=Sign policy=http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256Endpoint opc.tcp://localhost:4840/pdcomm mode=SignAndEncrypt policy=http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256Endpoint opc.tcp://localhost:4840/pdcomm mode=Sign policy=http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaepEndpoint opc.tcp://localhost:4840/pdcomm mode=SignAndEncrypt policy=http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaepEndpoint opc.tcp://localhost:4840/pdcomm mode=Sign policy=http://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPssEndpoint opc.tcp://localhost:4840/pdcomm mode=SignAndEncrypt policy=http://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPssSession activated (anonymous)Read ns=2;i=1001 value=42 service=0x00000000 status=0x00000000Session closedservice는 서비스 결과, status는 읽은 값의 StatusCode입니다. 둘 다 0x00000000(Good)이면 성공입니다. 종료 코드는 0입니다.
6. 값 쓰기
섹션 제목: “6. 값 쓰기”--write로 값을 쓰고 다시 읽습니다.
build/opcua_client opc.tcp://localhost:4840/pdcomm \ examples/opcua/pki/client.der examples/opcua/pki/client.key.pem examples/opcua/pki/server.der --write 7출력의 마지막 세 줄은 다음과 같습니다.
Write ns=2;i=1001 value=7 service=0x00000000 status=0x00000000Read ns=2;i=1001 value=7 service=0x00000000 status=0x00000000Session closed7. 정리
섹션 제목: “7. 정리”서버 터미널에서 Ctrl+C를 누릅니다. 서버는 마지막 값을 출력하고 끝납니다.
Final Value=7Server stopped문제가 생기면
섹션 제목: “문제가 생기면”| 오류 문장 | 원인과 조치 |
|---|---|
Error: discover failed (SDK status 5): OPC UA I/O: connection refused (os error 61) |
서버가 실행 중이 아니거나 포트가 다릅니다. 서버 터미널과 URL의 포트를 확인합니다. |
Error: connect failed (SDK status 5): OPC UA security CertificateUntrusted |
클라이언트에 지정한 서버 인증서가 실제 서버 인증서와 다릅니다. 서버가 쓰는 server.der를 지정합니다. |
Error: connect failed (SDK status 5): OPC UA status: 0x80130000 |
서버가 이 클라이언트 인증서를 신뢰하지 않습니다(BadSecurityChecksFailed). 서버의 마지막 인자를 클라이언트의 client.der로 바꾸고 서버를 다시 시작합니다. |
Error: cannot read the certificate, private key or trusted server certificate |
파일 경로가 틀렸거나 파일이 비었습니다. SDK 루트에서 실행했는지 확인합니다. |
더 많은 오류는 문제 해결에서 찾습니다.
다음 단계
섹션 제목: “다음 단계”- C 클라이언트 튜토리얼: 이 예제의 코드를 읽고 Browse와 Call을 실행합니다.
- 튜토리얼 목록: C++, Qt, .NET, 구독, 이벤트, 이력, PubSub
- 시뮬레이터 GUI: 코드를 쓰지 않고 서버와 클라이언트를 실습합니다.