FB_TCPServer/FB_TCPServer2

Überblick

Typ:

Funktionsbaustein

Verfügbar ab:

V1.0.4.0

Übernommen aus:

-

Implementiert:

-

Aufgabe

Der TCP-Server überwacht einen angegebenen Port auf eingehende Client-Verbindungen und verarbeitet sie. Nachdem die Verbindung angenommen wurde, können Client-Daten empfangen und Daten an einen oder alle Clients gesendet werden.

Funktionsbeschreibung

Die Bibliothek stellt zwei Versionen des FB_TCPServer-Funktionsbausteins zur Verfügung. Der FB_TCPServer2 ist eine verbesserte Version, die Verbindungen über TLS (Transport Layer Security) unterstützt.

Ob eine Verbindung unter Verwendung TLS unterstützt wird, ist von der Steuerung abhängig, auf der der FB_TcpServer2 zum Einsatz kommt. Prüfen Sie im spezifischen Handbuch Ihrer Steuerung, ob Unterstützung für die TCP-Kommunikation mit TLS geboten wird.

Das Funktionsprinzip für die beiden Funktionsbausteine ist identisch. Es gibt einige Unterschiede bei den angegebenen Eigenschaften und Methoden, die in den jeweiligen Kapiteln erläutert werden.

Üblicherweise wird zunächst die Methode Open oder OpenTls aufgerufen, dabei werden eine TCP-Port-Nummer sowie ggf. die IP-Adresse der zu überwachenden Schnittstelle angegeben. Anschließend wird der Wert der Eigenschaft State solange zyklisch abgerufen, bis er von Opening abweicht. Wenn sich der Status nicht in Opened ändert, ist ein Fehler aufgetreten. Prüfen Sie den Wert der Eigenschaft Result, um den Grund dafür zu ermitteln.

Bei erfolgreicher Ausführung (Status = Opened) ist der Server bereit, eingehende Verbindungen anzunehmen. Dies ist an der Eigenschaft IsNewConnectionAvailable erkennbar. Sie muss regelmäßig von der Anwendung überprüft werden. Lautet der Wert TRUE, muss die Methode Accept aufgerufen werden. Sie gibt die IP-Adresse und den Port zurück, von dem die Verbindung stammt. Sie können nun programmseitig festlegen, ob die Verbindung beibehalten werden soll. Die Anzahl an verbundenen Clients ist aus der Eigenschaft NumberOfConnectedClients ersichtlich.

Die Eigenschaft IsDataAvailable gibt an, ob vom Client an den Server gesendete Daten vorliegen, die gelesen werden können. Mithilfe der Methoden ReceiveFromFirstAvailableClient und PeekFromFirstAvailableClient können die Daten vom ersten Client gelesen werden, auf dem Daten verfügbar sind, ohne dass die IP-Adresse oder die Portnummer des Clients vorliegen. Da vor dem Aufrufen der Methode nicht festgelegt wurde, wessen Daten gelesen werden sollen, werden die IP-Adresse und der Port des Clients als Methodenausgang geliefert. Sofern in dieser Beschreibung nicht anders angegeben, sind die Methoden FB_TCPServer/FB_TCPServer2 und FB_TCPClient/FB_TCPClient2 gleich.

Mit der Methode SendToSpecificClient kann einem bestimmten Client nach dem Empfang seiner Daten über die Methode ReceiveFromFirstAvailableClient direkt geantwortet werden. Die Anwendung muss dem TCP-Server daher die IP-Adresse und den Port des verbundenen Clients liefern. Anschließend verhält sie sich wie die Methode Send unter FB_TCPClient/FB_TCPClient2.

Um Daten an die verbundenen Clients zu senden, verwenden Sie die Methode SendToAll. Bei der Methode SendToAll wird die Übertragung an einen Client beendet, wenn bei diesem Client ein Fehler auftritt, und die Anzahl der gesendeten Bytes wird zurückgegeben. Durch Vergleichen der Summe der gesendeten Bytes mit der zu sendenden Datenmenge multipliziert mit der Anzahl der Clients kann ermittelt werden, ob alle Bytes an alle Clients gesendet wurden.

Wenn der TCP-Server den Status Listening aufweist, muss die Methode CheckClients zyklisch aufgerufen werden, um zu ermitteln, ob ein Client die Verbindung geschlossen hat. Alternativ kann auch die Eigenschaft NumberOfConnectedClients aufgerufen werden. Wenn eine vom Client initiierte Trennung erkannt wird und keine, aus dieser Client-Verbindung stammenden Daten mehr gelesen werden müssen, wird sie geschlossen und einer neuen eingehenden Verbindung bereitgestellt. Andernfalls bleibt die Verbindung verfügbar, bis die Daten gelesen wurden oder bis die Methode DisconnectClient für diese Verbindung aufgerufen wird. Wenn die Methode DisconnectClient aufgerufen wird, werden die Daten von dem angegebenen Client, die noch nicht verarbeitet wurden, verworfen.

Ist die Verarbeitung durch eine Methode nicht erfolgreich verlaufen, wird dies durch den Wert der Eigenschaft Result angegeben. Der Wert von Result muss nach jedem Methodenaufruf geprüft werden. Das Ergebnis kann auf Ok zurückgesetzt werden. Dazu dient die Methode ResetResult.

HINWEIS: Alle Methoden sind blockiert, solange der Wert der Eigenschaft Result ungleich Ok ist. Ein Methodenaufruf in diesem Fall wird ohne Beeinflussung der Informationen der Eigenschaft Result abgebrochen.

Schnittstelle

Der Funktionsbaustein weist keine Eingänge und Ausgänge auf. Die Funktionalität ist über Methode und Eigenschaften verfügbar. Um getrennte Clients zu erkennen, muss die Methode CheckClients zyklisch aufgerufen werden. Alternativ kann auch der Wert der Eigenschaft NumberOfConnectedClients aufgerufen werden. Mit beidem kann geprüft werden, ob die Clients weiterhin verbunden sind oder die Verbindung getrennt haben.

Implementierungsbeispiel

PROGRAM LibDocu_TcpServer2
VAR
    xOpen : BOOL;
    xOpenTls : BOOL;
    xClose : BOOL;
    etResult : TCPUDP.ET_Result;
    etState : TCPUDP.ET_State;
    iState : INT;
    fbTcpServer : TCPUDP.FB_TCPServer2;
    stTlsSettings : TCPUDP.ST_TlsSettingsServer;
    sIp : STRING(15) := '';
    uiPort : UINT := 12345;
END_VAR
CASE iState OF
    0: // idle
        IF xOpen OR xOpenTls THEN
            IF xOpen AND_THEN NOT fbTcpServer.Open(sIp, uiPort) THEN
                iState := 100; // error state
            ELSIF xOpenTls AND_THEN NOT fbTcpServer.OpenTls(sIp, uiPort, stTlsSettings) THEN
                iState := 100; // error state
            END_IF			
            xOpen := xOpenTls := FALSE;
        END_IF
        IF fbTcpServer.State = TCPUDP.ET_State.Listening THEN
            iState := 10;
        END_IF
    10: // listening
        IF fbTcpServer.State = TCPUDP.ET_State.Idle THEN
            iState := 0; 
        ELSIF fbTcpServer.State <> TCPUDP.ET_State.Listening AND fbTcpServer.State <> TCPUDP.ET_State.Closing THEN
            iState := 100; // unexpected state
        ELSIF fbtcpserver.IsNewConnectionAvailable THEN
            fbTcpServer.Accept();
            iState := 20; // state accepting
        ELSE
            IF xClose THEN
                xClose := FALSE;
                fbTcpServer.Close();
            END_IF

            (* your code comes here, e.g. check for data available to read *)

        END_IF
    20: // accepting
        IF fbTcpServer.State <> TCPUDP.ET_State.Accepting AND fbTcpServer.State <> TCPUDP.ET_State.Listening THEN
            iState := 100; // unexpected, go to error state
        ELSIF fbTcpServer.State = TCPUDP.ET_State.Listening THEN
            iState := 10;// incoming connection successful accepted
        END_IF
    100: // error state
        (* your code comes here*)
END_CASE
etResult := fbTcpServer.Result;
etState := fbTcpServer.State;