FB_TCPServer/FB_TCPServer2

Overview

Type:

Function block

Available as of:

V1.0.4.0

Inherits from:

-

Implements:

-

Task

The TCP server monitors for and processes incoming client-connections on a specified port. After a connection has been accepted, data can be received from clients and data can be sent to one or to all clients.

Functional Description

The library provides two versions of the FB_TCPServer function block. The FB_TCPServer2 is an enhanced version which supports connections using TLS (Transport Layer Security).

Whether a connection using TLS is supported depends on the controller where the FB_TcpServer2 is used. Refer to the specific manual of your controller to verify if TCP communication using TLS is supported.

The working principle for both function blocks is the same. There are some differences for the provided properties and methods which are described in the respective chapters.

The usual order of commands is to call the Open or OpenTls method first, specifying a TCP port number and optionally an IP address of an interface to monitor on. Afterwards, retrieve the value of the State property cyclically until it is other than Opening. If the state does not transition to Opened, an error has occurred. Verify the value of the Result property to determine the reason.

When successful (State = Opened), the server is ready to accept incoming connections. It is indicated via the property IsNewConnectionAvailable. It must be verified periodically by the application and, in case the value is TRUE, the Accept method must be called. It returns the IP address and the port the connection is coming from. You can then programmatically determine whether to maintain the connection. The number of connected clients can be verified using the NumberOfConnectedClients property.

To verify whether a client has sent data to the server that is now available to read, use the property IsDataAvailable. The methods ReceiveFromFirstAvailableClient and PeekFromFirstAvailableClient can be used to read the data from the first client that has data available without having the IP and port of the client. Since it is undetermined by the application from which client the data is read from before calling the method, IP and port of the client are provided as outputs of the methods. Unless otherwise noted in the present description, the FB_TCPServer/FB_TCPServer2 methods operate as does the FB_TCPClient/FB_TCPClient2 .

The method SendToSpecificClient can be used to reply directly to a specific client after data has been received using the ReceiveFromFirstAvailableClient method. Therefore the application has to provide the IP address and port of a client connected to the TCP server. It then behaves like the Send method of FB_TCPClient/FB_TCPClient2.

To send data to the connected clients, use the SendToAll method. When using the SendToAll method, an error from the client terminates the transmission to that client, and the number of bytes sent is returned. Thereafter, you can determine whether the bytes have been sent to the clients by comparing the sum of the bytes sent with the amount of data to be sent multiplied by the number of clients.

While the state of the TCP server is Listening, the method CheckClients must be called cyclically to detect if a client has closed the connection. Alternatively, the property NumberOfConnectedClients can be retrieved. If a client-initiated disconnection has been detected and there is no more data to be read from that client connection, it is closed and made available for a new incoming connection. Otherwise, the connection is kept available until the data has been read or until the DisconnectClient method is called for that connection. When calling the method DisconnectClient, the data received from the specified client that has not yet been processed are discarded.

If processing in a method is unsuccessful, it is indicated in the value of the Result property. The value of Result must be verified after every method call. The result can be reset to Ok using the ResetResult method.

NOTE: All methods are blocked as long as the value of the property Result is unequal to Ok. A method call in this case is aborted without affecting the information of the Result property.

Interface

The function block does not have inputs and outputs. The functionality is available via methods and properties. In order to detect disconnections from connected clients, the method CheckClients must be called cyclically. Alternatively the value of the property NumberOfConnectedClients can be retrieved. Either can verify that clients are still connected or have closed the connection.

Implementation Example

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;