Building a Simple Server

This series of tutorial guide you through your first steps with open62541. For compiling the examples, you need a compiler (MS Visual Studio 2015 or newer, GCC, Clang and MinGW32 are all known to be working). The compilation instructions are given for GCC but should be straightforward to adapt.

It will also be very helpful to install an OPC UA Client with a graphical frontend, such as UAExpert by Unified Automation. That will enable you to examine the information model of any OPC UA server.

To get started, downdload the open62541 single-file release from or generate it according to the build instructions with the “amalgamation” option enabled. From now on, we assume you have the open62541.c/.h files in the current folder. Now create a new C source-file called myServer.c with the following content:

#include <open62541/plugin/log_stdout.h>
#include <open62541/server.h>
#include <open62541/server_config_default.h>

#include <signal.h>
#include <stdlib.h>

static volatile UA_Boolean running = true;
static void stopHandler(int sig) {
    UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c");
    running = false;

int main(void) {
    signal(SIGINT, stopHandler);
    signal(SIGTERM, stopHandler);

    UA_Server *server = UA_Server_new();

    UA_StatusCode retval = UA_Server_run(server, &running);


This is all that is needed for a simple OPC UA server. With the GCC compiler, the following command produces an executable:

$ gcc -std=c99 open62541.c myServer.c -o myServer

In a MinGW environment, the Winsock library must be added.

$ gcc -std=c99 open62541.c myServer.c -lws2_32 -o myServer.exe

Now start the server (stop with ctrl-c):

$ ./myServer

You have now compiled and run your first OPC UA server. You can go ahead and browse the information model with client. The server is listening on opc.tcp://localhost:4840. In the next two sections, we will continue to explain the different parts of the code in detail.

Server Configuration and Plugins

open62541 provides a flexible framework for building OPC UA servers and clients. The goals is to have a core library that accommodates for all use cases and runs on all platforms. Users can then adjust the library to fit their use case via configuration and by developing (platform-specific) plugins. The core library is based on C99 only and does not even require basic POSIX support. For example, the lowlevel networking code is implemented as an exchangeable plugin. But don’t worry. open62541 provides plugin implementations for most platforms and sensible default configurations out-of-the-box.

In the above server code, we simply take the default server configuration and add a single TCP network layer that is listerning on port 4840.

Server Lifecycle

The code in this example shows the three parts for server lifecycle management: Creating a server, running the server, and deleting the server. Creating and deleting a server is trivial once the configuration is set up. The server is started with UA_Server_run. Internally, the server then uses timeouts to schedule regular tasks. Between the timeouts, the server listens on the network layer for incoming messages.

You might ask how the server knows when to stop running. For this, we have created a global variable running. Furthermore, we have registered the method stopHandler that catches the signal (interrupt) the program receives when the operating systems tries to close it. This happens for example when you press ctrl-c in a terminal program. The signal handler then sets the variable running to false and the server shuts down once it takes back control.

In order to integrated OPC UA in a single-threaded application with its own mainloop (for example provided by a GUI toolkit), one can alternatively drive the server manually. See the section of the server documentation on Server Lifecycle for details.

The server configuration and lifecycle management is needed for all servers. We will use it in the following tutorials without further comment.