FB_TCPServer/FB_TCPServer2

Présentation

Type :

Bloc fonction

Disponible à partir de :

V1.0.4.0

Hérite de :

-

Implémente :

-

Tâche

Le serveur TCP surveille et traite les connexions client entrantes sur un port déterminé. Dès qu'une connexion a été acceptée, il est possible de recevoir des données de la part des clients, et d'en envoyer vers un client spécifique ou vers tous les clients.

Description fonctionnelle

La bibliothèque fournit deux versions du bloc fonction FB_TCPServer. Le FB_TCPServer2 est une version améliorée qui prend en charge les connexions en utilisant TLS (Transport Layer Security).

La prise en charge ou non d'une connexion utilisant le protocole TLS dépend du contrôleur sur lequel FB_TcpServer2 est utilisé. Consultez le manuel spécifique de votre contrôleur pour vérifier si la communication TCP qui utilise TLS est prise en charge.

Le principe de fonctionnement des blocs fonction est le même. Il y a quelques différences pour les propriétés fournies et les méthodes qui sont décrites dans les chapitres respectifs.

La méthode Open ou OpenTls est généralement appelée en premier. Un numéro de port TCP et, éventuellement, l'adresse IP d'une interface sur laquelle surveiller sont indiqués. L'étape suivante consiste à récupérer la valeur de la propriété State, de façon cyclique, jusqu'à ce qu'elle soit différente de Opening. Si l'état ne passe pas à Opened, une erreur s'est produite. Vous pouvez alors déterminer la cause du problème d'après la valeur de la propriété Result.

Si l'opération aboutit (état = Opened), le serveur est prêt à accepter des connexions entrantes. Comme indiqué par la propriété IsNewConnectionAvailable. Elle doit être vérifiée de façon cyclique par l'application. Si sa valeur est TRUE, la méthode Accept doit être appelée. L'adresse IP et le port d'origine de la connexion sont alors renvoyés. À l'aide d'un programme, vous pouvez ensuite décider de maintenir ou non la connexion. La propriété NumberOfConnectedClients permet de vérifier le nombre de clients connectés.

Pour vérifier si un client a envoyé des données au serveur et si celles-ci peuvent être lues, utilisez la propriété IsDataAvailable. Avec les méthodes ReceiveFromFirstAvailableClient et PeekFromFirstAvailableClient, il est possible de lire les données sur le premier client où des données sont disponibles sans connaître son adresse IP ni son port. Tant que la méthode n'est pas appelée, l'application ne permet pas de savoir à partir de quel client les données sont lues. L'adresse IP et le port du client sont donc fournies comme sorties des méthodes. Sauf mention contraire dans la présente description, le principe de fonctionnement des méthodes FB_TCPServer/FB_TCPServer2 est identique à celui de FB_TCPClient/FB_TCPClient2 .

La méthode SendToSpecificClient peut être utilisée pour répondre directement à un client après réception des données via la méthode ReceiveFromFirstAvailableClient. Dans ce cas, l'application doit fournir l'adresse IP et le port d'un client connecté au serveur TCP. Le principe est ensuite le même qu'avec la méthode Send de FB_TCPClient/FB_TCPClient2.

Pour envoyer des données aux clients connectés, utilisez la méthode SendToAll. Avec la méthode SendToAll, une erreur du client met fin à la transmission vers ce dernier et le nombre d'octets envoyés est retourné. Par la suite, vous pouvez déterminer si tous les octets ont été envoyés à l'ensemble des clients en comparant la somme des octets envoyés et la quantité de données à envoyer multipliée par le nombre de clients.

Lorsque le serveur TCP est à l'état Listening, la méthode CheckClients doit être appelée de façon cyclique pour déterminer si un client a fermé la connexion. Il est aussi possible de récupérer la propriété NumberOfConnectedClients. En cas de déconnexion par un client et s'il n'y a plus aucune donnée à lire de cette connexion client, celle-ci est fermée et libérée pour permettre une nouvelle connexion entrante. Sinon, la connexion est maintenue disponible jusqu'à la lecture des données ou l'appel de la méthode DisconnectClient pour cette connexion. Lors de l'appel de la méthode DisconnectClient, les données reçues du client indiqué non encore traitées sont rejetées.

L'échec du traitement d'une méthode est indiqué dans la valeur de la propriété Result. La valeur de Result doit être vérifiée après chaque appel de méthode. La méthode ResetResult permet de réinitialiser le résultat sur Ok.

NOTE : Toutes les méthodes sont bloquées tant que la valeur de la propriété Result est différente de Ok. Dans ce cas, un appel de méthode est annulé, sans modification des informations de la propriété Result.

Interface

Le bloc fonction n'a ni entrées, ni sorties. Il remplit sa fonction par le biais de méthodes et de propriétés. Afin de détecter les déconnexions des clients connectés, la méthode CheckClients doit être appelée cycliquement. Vous pouvez aussi récupérer la propriété NumberOfConnectedClients. Vous pouvez vérifier que les clients sont encore connectés ou si la connexion a été fermée.

Exemple de mise en œuvre

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;