# Konfiguration

> Anleitung: Den Server konfigurieren: Anwendung, Zertifikat, Serverendpunkte und Netzwerk-Bindung, Grenzen der Datenübertragung und XML-Konfiguration.

**Beispielanwendungen:**

- Server.ConfiguredViaCode ([C#](https://github.com/Traeger-GmbH/opcuanet-samples/tree/master/cs/Configuration/Server.ConfiguredViaCode), [VB.NET](https://github.com/Traeger-GmbH/opcuanet-samples/tree/master/vb/Configuration/Server.ConfiguredViaCode)): Zeigt verschiedene Wege, einen Server im Code zu konfigurieren, von der Standardkonfiguration bis zu eigenen Einstellungen.
- Server.ConfiguredViaXml ([C#](https://github.com/Traeger-GmbH/opcuanet-samples/tree/master/cs/Configuration/Server.ConfiguredViaXml), [VB.NET](https://github.com/Traeger-GmbH/opcuanet-samples/tree/master/vb/Configuration/Server.ConfiguredViaXml)): Lädt die Konfiguration eines Servers aus einer XML-Datei.

## Anwendung konfigurieren

Beteiligte Typen: `OpcServer`, `OpcApplicationConfiguration`, `OpcCertificateStores`, `OpcCertificateStoreInfo`

Alle Codeausschnitte auf dieser Seite konfigurieren den Server im Code, sofern sie nicht mit der Standardkonfiguration des Servers arbeiten. Zentrale Anlaufstelle für die Konfiguration der Serveranwendung ist die Instanz von `OpcServer`. Die Einstellungen zur Sicherheit stellt der Server als Instanz der Klasse `OpcServerSecurity` über seine Eigenschaft `Security` bereit. Die Einstellungen zu den Zertifikatspeichern stellt er als Instanz der Klasse `OpcCertificateStores` über die Eigenschaft `CertificateStores` bereit.

Wenn der Server auch per XML konfigurierbar sein soll, können Sie seine Konfiguration aus einer XML-Datei laden. Den Aufbau der Datei zeigt der Abschnitt [Konfiguration per XML-Datei](https://www.traeger.de/docs/development/opcua/server/configuration#konfiguration-per-xml-datei). So laden Sie die Einstellungen:

**Konfigurationsdatei über den Namen der Konfiguration laden**: Die Methode `LoadServerConfig` sucht im Arbeitsverzeichnis der Anwendung die Datei `<Name>.Config.xml`, im folgenden Beispiel also `Opc.UaFx.Server.Config.xml`.

```csharp
server.Configuration = OpcApplicationConfiguration.LoadServerConfig("Opc.UaFx.Server");

```

```vbnet
server.Configuration = OpcApplicationConfiguration.LoadServerConfig("Opc.UaFx.Server")

```

**Konfigurationsdatei über den Pfad zur XML-Datei laden**: Wenn die Datei nicht gefunden oder nicht gelesen werden kann, lösen `LoadServerConfig` und `LoadServerConfigFile` keine Ausnahme aus, sondern liefern `null`. Wenn Sie diesen Wert der Eigenschaft `Configuration` zuweisen, startet der Server ohne Hinweis mit seiner Standardkonfiguration. Prüfen Sie deshalb den Rückgabewert:

```csharp
var configuration = OpcApplicationConfiguration.LoadServerConfigFile(
        "MyServerAppNameConfig.xml");
 
// The method returns a null reference in case the file could not be loaded.
if (configuration == null)
    throw new InvalidOperationException("The server configuration could not be loaded.");
 
server.Configuration = configuration;

```

```vbnet
Dim configuration = OpcApplicationConfiguration.LoadServerConfigFile( _
        "MyServerAppNameConfig.xml")

'The method returns a null reference in case the file could not be loaded.
If configuration Is Nothing Then
    Throw New InvalidOperationException("The server configuration could not be loaded.")
End If

server.Configuration = configuration
```

Die Serveranwendung lässt sich unter anderem auf die folgenden Arten konfigurieren:

**Anwendung konfigurieren** (per Code). Ohne Angabe verwendet der Server als `ApplicationName` den Wert des Attributs `AssemblyTitle`, ersatzweise den des Attributs `AssemblyProduct` und andernfalls `OPC Application`. Die `ApplicationUri` übernimmt der Server beim Start aus dem Subject Alternative Name seines Anwendungszertifikats. Ein im Code festgelegter Wert wird dabei überschrieben. Der Server verwendet ihn nur, wenn er ein neues Zertifikat erzeugt:

```csharp
// Default: Value of AssemblyTitleAttribute of entry assembly.
server.ApplicationName = "MyServerAppName";
 
// Default: A null reference to use the URI of the application certificate.
// The value is used to create a new application certificate.
server.ApplicationUri = new Uri("urn:localhost:MyServerAppName");
```

```vbnet
'Default: Value of AssemblyTitleAttribute of entry assembly.
server.ApplicationName = "MyServerAppName"

'Default: A null reference to use the URI of the application certificate.
'The value is used to create a new application certificate.
server.ApplicationUri = New Uri("urn:localhost:MyServerAppName")
```

Per XML (unterhalb des Elements `OpcApplicationConfiguration`):

```xml
<ApplicationName>MyServerAppName</ApplicationName>
<ApplicationUri>urn:localhost:MyServerAppName</ApplicationUri>
```

**Zertifikatspeicher konfigurieren** (per Code). Standardmäßig liegen die Zertifikatspeicher im Ordner `CertificateStores` neben der Anwendung: das Anwendungszertifikat in `CertificateStores\App`, abgelehnte Zertifikate in `CertificateStores\Rejected` und vertrauenswürdige Zertifikate sowie Aussteller in `CertificateStores\Trusted`. Ist das Verzeichnis der Anwendung nicht beschreibbar, verwendet der Server stattdessen `%ProgramData%\OPC Foundation\CertificateStores` beziehungsweise `%AppData%\OPC Foundation\CertificateStores`. Welche Pfade der Server in welcher Reihenfolge prüft, legt die Eigenschaft `OpcCertificateStores.PathProbings` fest:

```csharp
// Default: ".\CertificateStores\App"
server.CertificateStores.ApplicationStore.Path
        = @"%LocalApplicationData%\MyServerAppName\App Certificates";
 
// Default: ".\CertificateStores\Rejected"
server.CertificateStores.RejectedStore.Path
        = @"%LocalApplicationData%\MyServerAppName\Rejected Certificates";
 
// Default: ".\CertificateStores\Trusted"
server.CertificateStores.TrustedIssuerStore.Path
        = @"%LocalApplicationData%\MyServerAppName\Trusted Issuer Certificates";
 
// Default: ".\CertificateStores\Trusted"
server.CertificateStores.TrustedPeerStore.Path
        = @"%LocalApplicationData%\MyServerAppName\Trusted Peer Certificates";
```

```vbnet
'Default: ".\CertificateStores\App"
server.CertificateStores.ApplicationStore.Path _
        = "%LocalApplicationData%\MyServerAppName\App Certificates"

'Default: ".\CertificateStores\Rejected"
server.CertificateStores.RejectedStore.Path _
        = "%LocalApplicationData%\MyServerAppName\Rejected Certificates"

'Default: ".\CertificateStores\Trusted"
server.CertificateStores.TrustedIssuerStore.Path _
        = "%LocalApplicationData%\MyServerAppName\Trusted Issuer Certificates"

'Default: ".\CertificateStores\Trusted"
server.CertificateStores.TrustedPeerStore.Path _
        = "%LocalApplicationData%\MyServerAppName\Trusted Peer Certificates"
```

Per XML (unterhalb des Elements `OpcApplicationConfiguration`):

```xml
<SecurityConfiguration>
  <ApplicationCertificate>
    <StoreType>Directory</StoreType>
    <StorePath>%LocalApplicationData%\MyServerAppName\CertificateStores\App Certificates</StorePath>
    <SubjectName>MyServerAppName</SubjectName>
  </ApplicationCertificate>

  <RejectedCertificateStore>
    <StoreType>Directory</StoreType>
    <StorePath>%LocalApplicationData%\MyServerAppName\CertificateStores\Rejected Certificates</StorePath>
  </RejectedCertificateStore>

  <TrustedIssuerCertificates>
    <StoreType>Directory</StoreType>
    <StorePath>%LocalApplicationData%\MyServerAppName\CertificateStores\Trusted Issuer Certificates</StorePath>
  </TrustedIssuerCertificates>

  <TrustedPeerCertificates>
    <StoreType>Directory</StoreType>
    <StorePath>%LocalApplicationData%\MyServerAppName\CertificateStores\Trusted Peer Certificates</StorePath>
  </TrustedPeerCertificates>
</SecurityConfiguration>
```

**Produktinformationen des Servers**: Hersteller, Produktname und Version sehen Clients in den Statusinformationen des Servers (BuildInfo). Der Server ermittelt sie aus der Einstiegs-Assembly der Anwendung: den Hersteller aus `AssemblyCompany`, den Produktnamen aus `AssemblyTitle` und die Version aus `AssemblyVersion`. Wenn `ApplicationName` gesetzt ist, verwendet er als Produktnamen stattdessen diesen Wert. Die Informationen rufen Sie mit `GetInfo` ab:

```csharp
OpcServerInfo info = server.GetInfo();
 
Console.WriteLine("{0} {1} {2}", info.CompanyName, info.ProductName, info.ProductVersion);
Console.WriteLine("Product URI: {0}", info.ProductUri);
```

```vbnet
Dim info As OpcServerInfo = server.GetInfo()

Console.WriteLine("{0} {1} {2}", info.CompanyName, info.ProductName, info.ProductVersion)
Console.WriteLine("Product URI: {0}", info.ProductUri)
```

```csharp
[assembly: AssemblyCompany("Example Machines Ltd.")]
[assembly: AssemblyTitle("Example Machine Server")]
[assembly: AssemblyVersion("1.2.0.0")]
```

```vbnet
<Assembly: AssemblyCompany("Example Machines Ltd.")>
<Assembly: AssemblyTitle("Example Machine Server")>
<Assembly: AssemblyVersion("1.2.0.0")>
```

Wenn die Informationen nicht aus der Assembly stammen sollen, zum Beispiel um zusätzlich eine Produkt-URI anzugeben, überschreiben Sie in einer abgeleiteten Serverklasse die Methode `GetInfoCore`:

```csharp
public class MachineServer : OpcServer
{
    public MachineServer()
        : base("opc.tcp://localhost:4840/")
    {
    }
 
    protected override OpcServerInfo GetInfoCore()
    {
        return new OpcServerInfo(
                companyName: "Example Machines Ltd.",
                productName: "Example Machine Server",
                productVersion: new Version(1, 2, 0, 0),
                buildDate: new DateTime(2026, 1, 15),
                productUri: new Uri("urn:example:machine-server"));
    }
}
```

```vbnet
Public Class MachineServer
    Inherits OpcServer

    Public Sub New()
        MyBase.New("opc.tcp://localhost:4840/")
    End Sub

    Protected Overrides Function GetInfoCore() As OpcServerInfo
        Return New OpcServerInfo( _
                companyName:="Example Machines Ltd.", _
                productName:="Example Machine Server", _
                productVersion:=New Version(1, 2, 0, 0), _
                buildDate:=New DateTime(2026, 1, 15), _
                productUri:=New Uri("urn:example:machine-server"))
    End Function
End Class

```

## Anwendungszertifikat

Beteiligte Typen: `OpcServer`, `OpcCertificateManager`, `OpcCertificateSettings`, `OpcServerSecurity`, `OpcCertificateStores`, `OpcCertificateStoreInfo`

Das OPC UA .NET SDK lädt Zertifikate der Dateitypen `.der` und `.cer` (nur der öffentliche Teil) sowie `.pfx` und `.p12` (mit privatem Schlüssel). Wenn der Server einen sicheren Endpunkt bereitstellen soll, muss das Zertifikat einen privaten Schlüssel haben. Ein sicherer Endpunkt verwendet den `OpcSecurityMode` `Sign` oder `SignAndEncrypt`.

**1.** So laden Sie ein **vorhandenes Zertifikat** von einem beliebigen Pfad:

```csharp
var certificate = OpcCertificateManager.LoadCertificate("MyServerCertificate.pfx");
```

```vbnet
Dim certificate = OpcCertificateManager.LoadCertificate("MyServerCertificate.pfx")
```

Ein durch ein Passwort geschütztes Zertifikat laden Sie unter Angabe des Passworts:

```csharp
var certificate = OpcCertificateManager.LoadCertificate(
        "MyServerCertificate.pfx",
        password: "password");
```

```vbnet
Dim certificate = OpcCertificateManager.LoadCertificate( _
        "MyServerCertificate.pfx", _
        password:="password")
```

**2.** So erzeugen Sie ein **neues Zertifikat** im Speicher:

```csharp
var certificate = OpcCertificateManager.CreateCertificate(server);

```

```vbnet
certificate = OpcCertificateManager.CreateCertificate(server)

```

Wenn Sie dabei Eigenschaften des Zertifikats festlegen wollen, verwenden Sie die Klasse `OpcCertificateSettings`. Dazu gehören zum Beispiel die Gültigkeit in Monaten (standardmäßig 600), die `ApplicationUri` oder die Namen der Domänen, unter denen der Server erreichbar ist. Die Eigenschaft `Organization` nimmt die Organisation (O) in den Antragsteller (engl. subject) des Zertifikats auf, sofern Sie keinen eigenen `SubjectName` festlegen:

```csharp
// Lifetime in months, default: 600.
var settings = new OpcCertificateSettings("MyServerAppName") {
    ApplicationUri = new Uri("urn:localhost:MyServerAppName"),
    Lifetime = 60
};
 
settings.DomainNames.Add("localhost");
 
var certificate = OpcCertificateManager.CreateCertificate(settings);
```

```vbnet
'Lifetime in months, default: 600.
Dim settings = New OpcCertificateSettings("MyServerAppName") With { _
    .ApplicationUri = New Uri("urn:localhost:MyServerAppName"), _
    .Lifetime = 60 _
}

settings.DomainNames.Add("localhost")

Dim certificate = OpcCertificateManager.CreateCertificate(settings)
```

Ein Zertifikat, das das SDK selbst für den Server erzeugt, nennt als Organisation den Hersteller aus den Produktinformationen des Servers. Außerdem enthält es den vollqualifizierten Namen des Rechners, sofern er sich per DNS auflösen lässt.

**3.** So speichern Sie das Zertifikat unter einem beliebigen Pfad:

```csharp
OpcCertificateManager.SaveCertificate("MyServerCertificate.pfx", certificate);

```

```vbnet
OpcCertificateManager.SaveCertificate("MyServerCertificate.pfx", certificate)

```

**4.** Das Serverzertifikat festlegen:

```csharp
server.Certificate = certificate;

```

```vbnet
server.Certificate = certificate

```

**5.** Das Zertifikat muss im Zertifikatspeicher für **Anwendungszertifikate** (`ApplicationStore`) gespeichert sein:

```csharp
if (!server.CertificateStores.ApplicationStore.Contains(certificate))
    server.CertificateStores.ApplicationStore.Add(certificate);

```

```vbnet
If Not server.CertificateStores.ApplicationStore.Contains(certificate) Then
    server.CertificateStores.ApplicationStore.Add(certificate)
End If

```

**6.** Wenn Sie **kein Zertifikat** festlegen, sucht der Server im `ApplicationStore` ein Zertifikat, dessen Name dem `ApplicationName` entspricht. Zuvor löst er das Ereignis `CertificateRequested` aus, über das die Anwendung selbst ein Zertifikat bereitstellen kann. Wenn der Server kein Zertifikat findet, erzeugt er standardmäßig automatisch ein neues Zertifikat und verwendet es. Bis Version 2.58 gilt das auch für ein ungültiges Zertifikat. Ab Version 2.59 behält der Server ein vorhandenes, aber ungültiges Zertifikat und löst das Ereignis `CertificateRequested` mit dem Grund aus (siehe [Eigenes Zertifikat schützen](https://www.traeger.de/docs/development/opcua/security/server#eigenes-zertifikat-schutzen)). Wenn auch das fehlschlägt, verwendet der Server ein temporäres Zertifikat im Speicher. Wenn der Server nur das angegebene Zertifikat verwenden soll, deaktivieren Sie diese Funktion. Setzen Sie dazu die Eigenschaft `AutoCreateCertificate` auf `false`:

```csharp
server.CertificateStores.AutoCreateCertificate = false;

```

```vbnet
server.CertificateStores.AutoCreateCertificate = False

```

Die Seite [Server absichern](https://www.traeger.de/docs/development/opcua/security/server) beschreibt, wie der Server Benutzeridentitäten verwaltet, Clientzertifikate prüft und seine Endpunkte und Netzwerkschnittstellen absichert. Sie zeigt auch, wie Sie den Server für den Produktivbetrieb härten.

## Endpunkte

Beteiligte Typen: `OpcServer`, `OpcServerSecurity`, `OpcSecurityPolicy`, `OpcSecurityMode`, `OpcSecurityAlgorithm`

Die Endpunkte (engl. Endpoints) des Servers ergeben sich aus dem Kreuzprodukt der verwendeten Basis-Adressen und der konfigurierten Sicherheitsstrategien für Endpunkte. Eine Basis-Adresse setzt sich aus einem unterstützten Paar aus Schema und Port sowie dem Host (IP-Adresse oder DNS-Name) zusammen. Für den Datenaustausch lassen sich mehrere Schemen auf unterschiedlichen Ports festlegen, möglich sind `opc.tcp` und `https`. Andere Schemen weist der Server mit einer `ArgumentException` zurück.

Standardmäßig verwendet der Server keine spezielle Strategie (engl. Policy), um einen sicheren Endpunkt bereitzustellen. Deshalb gibt es genauso viele Endpunkte wie Basis-Adressen. Wenn ein Server genau eine Basis-Adresse definiert, gibt es nur einen Endpunkt mit dieser Basis-Adresse und der Sicherheitsstrategie mit dem Modus `None`. Bei n verschiedenen Basis-Adressen gibt es ebenso nur n verschiedene Endpunkte mit derselben Sicherheitsstrategie. Auch mit nur einer speziellen Sicherheitsstrategie bleibt es bei n Endpunkten, alle mit genau dieser Strategie. Bei m verschiedenen Sicherheitsstrategien (s<sub>1</sub> bis s<sub>m</sub>) und n verschiedenen Basis-Adressen (b<sub>1</sub> bis b<sub>n</sub>) ergibt jede paarweise Verknüpfung aus Strategie und Basis-Adresse einen Endpunkt: s<sub>1</sub>+b<sub>1</sub>, s<sub>1</sub>+b<sub>2</sub> bis s<sub>1</sub>+b<sub>n</sub>, dann s<sub>2</sub>+b<sub>1</sub> bis s<sub>2</sub>+b<sub>n</sub> und so weiter bis s<sub>m</sub>+b<sub>n</sub>.

Neben dem Modus für die Sicherung der Kommunikation (Security-Modus) definiert die Sicherheitsstrategie eines Endpunkts einen Security-Algorithmus und einen Level. Laut OPC Foundation ist der Level ein relatives Maß für die Sicherheitsmechanismen, die ein Endpunkt verwendet. Per Definition ist ein Endpunkt mit einem höheren Level also sicherer als ein Endpunkt mit einem niedrigeren Level. Das ist allerdings nur eine Richtlinie, die niemand prüft oder durchsetzt. Den Level berechnet das SDK aus Modus und Algorithmus (Eigenschaft `OpcSecurityPolicy.Level`).

Wenn ein Server zum Beispiel zwei Sicherheitsstrategien (engl. Security Policies) verwendet, könnten sie so definiert sein:

- Sicherheitsstrategie A: Level=0, Security-Mode=None, Security-Algorithm=None
- Sicherheitsstrategie B: Level=1, Security-Mode=Sign, Security-Algorithm=Basic256Sha256

Dazu kommen zum Beispiel drei Basis-Adressen (engl. Base Addresses) für verschiedene Schemen:

- Basis-Adresse A: `"https://mydomain.com/"`
- Basis-Adresse B: `"opc.tcp://192.168.0.123:4840/"`
- Basis-Adresse C: `"opc.tcp://192.168.0.123:12345/"`

Das Kreuzprodukt ergibt daraus die folgenden Endpunktbeschreibungen:

- Endpunkt 1: Address=`"https://mydomain.com/"`, Level=0, Security-Mode=None, Security-Algorithm=None
- Endpunkt 2: Address=`"https://mydomain.com/"`, Level=1, Security-Mode=Sign, Security-Algorithm=Basic256Sha256
- Endpunkt 3: Address=`"opc.tcp://192.168.0.123:4840/"`, Level=0, Security-Mode=None, Security-Algorithm=None
- Endpunkt 4: Address=`"opc.tcp://192.168.0.123:4840/"`, Level=1, Security-Mode=Sign, Security-Algorithm=Basic256Sha256
- Endpunkt 5: Address=`"opc.tcp://192.168.0.123:12345/"`, Level=0, Security-Mode=None, Security-Algorithm=None
- Endpunkt 6: Address=`"opc.tcp://192.168.0.123:12345/"`, Level=1, Security-Mode=Sign, Security-Algorithm=Basic256Sha256

Die primäre Basis-Adresse legen Sie entweder im Konstruktor der Klasse `OpcServer` oder über die Eigenschaft `Address` einer Instanz von `OpcServer` fest. Ohne Angabe verwendet der Server die Adresse `opc.tcp://localhost:4840`:

```csharp
var server = new OpcServer("opc.tcp://localhost:4840/");
server.Address = new Uri("opc.tcp://localhost:4840/");

```

```vbnet
Dim server As New OpcServer("opc.tcp://localhost:4840/")
server.Address = New Uri("opc.tcp://localhost:4840/")

```

Wenn der Server weitere Basis-Adressen unterstützen soll, verwalten Sie diese mit den Methoden `RegisterAddress` und `UnregisterAddress`. Alle Basis-Adressen, die der Server verwendet, also alle registrierten, liefert die Eigenschaft `Addresses`. Wenn der Wert der Eigenschaft `Address` vorher nicht festgelegt wurde, übernimmt sie die erste Adresse, die Sie mit `RegisterAddress` definieren.

Zwei weitere Basis-Adressen definieren:

```csharp
server.RegisterAddress("https://mydomain.com/");
server.RegisterAddress("opc.tcp://192.168.0.123:12345/");
```

```vbnet
server.RegisterAddress("https://mydomain.com/")
server.RegisterAddress("opc.tcp://192.168.0.123:12345/")
```

Zwei Basis-Adressen vom Server entfernen (deregistrieren, engl. unregister), sodass sich auch die primäre Basis-Adresse ändert:

```csharp
server.UnregisterAddress("https://mydomain.com/");
 
// server.Address becomes: "opc.tcp://192.168.0.123:12345/"
server.UnregisterAddress("opc.tcp://localhost:4840/");
```

```vbnet
server.UnregisterAddress("https://mydomain.com/")

'server.Address becomes: "opc.tcp://192.168.0.123:12345/"
server.UnregisterAddress("opc.tcp://localhost:4840/")
```

Wenn Sie alle Adressen der Eigenschaft `Addresses` deregistrieren, ist auch der Wert der Eigenschaft `Address` nicht festgelegt.

So definieren Sie eine sichere Strategie für die Endpunkte des Servers. Ohne Angabe eines Algorithmus (`OpcSecurityAlgorithm.Auto`) wählt das SDK für `Sign` und `SignAndEncrypt` den Algorithmus `Basic256Sha256`. Weitere aktuelle Algorithmen sind zum Beispiel `Aes128_Sha256_RsaOaep` oder `Aes256_Sha256_RsaPss`. `Basic256` und `Basic128Rsa15` gelten als veraltet:

```csharp
server.Security.EndpointPolicies.Add(new OpcSecurityPolicy(
        OpcSecurityMode.Sign,
        OpcSecurityAlgorithm.Basic256Sha256));
```

```vbnet
server.Security.EndpointPolicies.Add(New OpcSecurityPolicy( _
        OpcSecurityMode.Sign, _
        OpcSecurityAlgorithm.Basic256Sha256))
```

Sobald Sie eine konkrete Sicherheitsstrategie für Endpunkte definieren, entfällt die standardmäßig verwendete Strategie mit dem Modus `None`. Diese Strategie ist für den produktiven Einsatz nicht zu empfehlen. Wenn der Server sie trotzdem unterstützen soll, tragen Sie sie explizit in die Liste der Endpunkt-Strategien ein:

```csharp
server.Security.EndpointPolicies.Add(new OpcSecurityPolicy(
	OpcSecurityMode.None, OpcSecurityAlgorithm.None));

```

```vbnet
server.Security.EndpointPolicies.Add(New OpcSecurityPolicy(
	OpcSecurityMode.None, OpcSecurityAlgorithm.None))

```

### An Netzwerkschnittstellen binden

Beteiligte Typen: `OpcServer`, `OpcServerBinding`, `OpcAddressScope`

An welche Netzwerkschnittstellen der Server seine Ports bindet, legt seine Eigenschaft `Binding` fest. Standardmäßig bindet der Server an alle IPv4- und IPv6-Adressen (`OpcAddressScope.IPvX`). Über die Eigenschaft `Addresses` lässt sich die Bindung auf bestimmte IP-Adressen beschränken. Außerdem bindet der Server seine Ports standardmäßig exklusiv (Eigenschaft `UseExclusiveAddress`), sodass kein zweiter Prozess denselben Port verwenden kann. Der Start eines zweiten Servers auf demselben Port schlägt dann fehl:

```csharp
// Default: OpcAddressScope.IPvX (IPv4 and IPv6)
server.Binding.AddressScope = OpcAddressScope.IPv4;
 
// Default: empty (bind to all network interfaces of the address scope)
server.Binding.Addresses.Add(IPAddress.Parse("192.168.0.123"));
 
// Default: true (only one process can bind to the port)
server.Binding.UseExclusiveAddress = false;
```

```vbnet
'Default: OpcAddressScope.IPvX (IPv4 and IPv6)
server.Binding.AddressScope = OpcAddressScope.IPv4

'Default: empty (bind to all network interfaces of the address scope)
server.Binding.Addresses.Add(IPAddress.Parse("192.168.0.123"))

'Default: True (only one process can bind to the port)
server.Binding.UseExclusiveAddress = False
```

## Grenzen der Datenübertragung

Beteiligte Typen: `OpcServer`, `OpcTransport`, `OpcOperationLimits`

Der Server begrenzt die Größe der Daten, die er mit seinen Clients austauscht. Überschreitet ein Wert eine dieser Grenzen, schlägt das Kodieren beziehungsweise Dekodieren fehl, zum Beispiel mit dem Status `BadEncodingLimitsExceeded`. Wenn Sie große Zeichenketten, Arrays oder Strukturen übertragen, können Sie die Grenzen über die Eigenschaft `Transport` des Servers erhöhen:

```csharp
server.Transport.MaxStringLength = 1048576;      // Default: 65535
server.Transport.MaxByteStringLength = 10485760; // Default: 5242880
server.Transport.MaxArrayLength = 1000000;       // Default: 65535
server.Transport.MaxMessageSize = 20971520;      // Default: 10485760
```

```vbnet
server.Transport.MaxStringLength = 1048576      'Default: 65535
server.Transport.MaxByteStringLength = 10485760 'Default: 5242880
server.Transport.MaxArrayLength = 1000000       'Default: 65535
server.Transport.MaxMessageSize = 20971520      'Default: 10485760
```

Die Werte entsprechen den Einträgen unterhalb des Elements `TransportQuotas` der XML-Konfiguration. Wie viele Nodes ein Client je Anfrage lesen, schreiben oder abonnieren darf, teilt der Server über seine Operation Limits mit. Standardmäßig meldet er keine Grenzen. Mit der Eigenschaft `OperationLimits` ermittelt der Server anhand der verfügbaren Systemressourcen geeignete Grenzen und meldet sie seinen Clients:

```csharp
// Default: false (the server does not announce any operation limits)
server.OperationLimits.AutoDetermineLimits = true;
```

```vbnet
'Default: False (the server does not announce any operation limits)
server.OperationLimits.AutoDetermineLimits = True
```

## Konfiguration per XML-Datei

Wenn der Server auch per XML konfigurierbar sein soll, können Sie seine Konfiguration aus einer XML-Datei laden. Die XML-Datei muss dazu den folgenden Standard-XML-Baum enthalten:

```xml
<?xml version="1.0" encoding="utf-8" ?>
<OpcApplicationConfiguration xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd">
</OpcApplicationConfiguration>
```

Unterhalb des Elements `OpcApplicationConfiguration` folgen dann die Einstellungen aus den vorherigen Abschnitten. Sie laden die Datei auf einem der folgenden Wege:

- **über den Pfad zur XML-Datei** mit der Methode `LoadServerConfigFile`. Die Datei kann einen beliebigen Namen haben und an einem beliebigen Ort liegen.
- **über den Namen der Konfiguration** mit der Methode `LoadServerConfig`. Die Datei muss dann `<Name>.Config.xml` heißen (zum Beispiel `Opc.UaFx.Server.Config.xml`) und im Arbeitsverzeichnis der Anwendung liegen.

Beide Methoden liefern `null`, wenn die Datei nicht gefunden oder nicht gelesen werden kann (siehe [Anwendung konfigurieren](https://www.traeger.de/docs/development/opcua/server/configuration#anwendung-konfigurieren)). Eine Konfiguration über die `App.config` der Anwendung (`configSections` mit einem Verweis auf die XML-Datei) unterstützt das SDK nicht.
