FB_TCPServer/FB_TCPServer2

Panoramica

Tipo:

Blocco funzione

Disponibile a partire da:

V1.0.4.0

Ereditato da:

-

Implementa:

-

Task

Il server TCP rileva l'arrivo delle richieste di connessione client su una porta specifica e poi le elabora. Dopo che una connessione è stata accettata, i dati possono essere ricevuti dai client e possono essere inviati a uno o a tutti i client.

Descrizione funzionale

La libreria fornisce due versioni del blocco funzione FB_TCPServer. Il FB_TCPServer2 è una versione ottimizzata che supporta connessioni che utilizzano TLS (Transport Layer Security).

Il supporto di una connessione che utilizza TLS dipende dal controller dove si usa il FB_TcpServer2. Consultare il manuale specifico del controller per verificare se è supportata la comunicazione tramite TCP.

Il principio di funzionamento di entrambi i blocchi funzione è lo stesso. Vi sono alcune differenze per metodi e proprietà forniti descritti nei rispettivi capitoli.

Il normale ordine di comandi è quello di richiamare prima il metodo Open o OpenTls, specificando un numero di porta TCP e facoltativamente un indirizzo IP di un'interfaccia da monitorare. Successivamente, recuperare ciclicamente il valore della proprietà State fino a quando è diversa da Opening. Se lo stato non passa a Opened, si è verificato un errore. Verificare il valore della proprietà Result per determinare il motivo.

Quando l'operazione è corretta (Stato = Opened), il server è pronto ad accettare le connessioni in entrata. Questo è indicato tramite la proprietà IsNewConnectionAvailable. Deve essere verificato periodicamente dall'applicazione e, nel caso in cui il valore è TRUE, deve essere richiamato il metodo Accept. Il comando restituisce l'indirizzo IP e la porta da cui proviene la connessione. È possibile quindi determinare in modo programmatico se mantenere o meno la connessione. Il numero di client collegati si può verificare tramite la proprietà NumberOfConnectedClients.

Per verificare se il client ha inviato dati al server che ora è pronto alla lettura, usare la proprietà IsDataAvailable. Possono essere utilizzati i metodi ReceiveFromFirstAvailableClient e PeekFromFirstAvailableClient per leggere i dati dal primo client con dati disponibili senza disporre dell'IP e della porta del client. Poiché non è l'applicazione che determina da quale client i dati vengono letti prima di chiamare il metodo, l'IP e la porta del client sono utilizzati come uscite dei metodi. Se non diversamente indicato nella presente descrizione, i metodi del parametro FB_TCPServer/FB_TCPServer2 operano come FB_TCPClient/FB_TCPClient2 .

Il metodo SendToSpecificClient può essere utilizzato per rispondere direttamente a un client specifico dopo che i dati sono stati ricevuti utilizzando il metodo ReceiveFromFirstAvailableClient. Pertanto l'applicazione deve fornire l'indirizzo IP e la porta del client collegato al server TCP. Esso si comporta quindi come il metodo Send del parametro FB_TCPClient/FB_TCPClient2.

Per inviare i dati ai client collegati, utilizzare il metodo SendToAll. Quando si utilizza il metodo SendToAll, un errore proveniente dal client chiude la trasmissione a tale client e viene restituito il numero di byte inviati. In seguito, è possibile determinare se i byte sono stati inviati ai client confrontando la somma dei byte inviati con la quantità di dati da inviare moltiplicata per il numero di client.

Mentre lo stato del server TCP è Listening, deve essere richiamato ciclicamente il metodo CheckClients per rilevare se un client ha chiuso la connessione. Alternativamente può essere ripristinata la proprietà NumberOfConnectedClients. Se è stata rilevata una disattivazione della connessione da parte di un client, e non vi sono più dati da leggere dalla connessione di quel client, essa viene chiusa e resa disponibile per una nuova connessione in arrivo. In caso contrario, la connessione viene mantenuta disponibile fino alla lettura di tutti i dati o alla chiamata del metodo DisconnectClient per tale connessione. Quando si chiama il metodo DisconnectClient, i dati ricevuti dal client specificato che non sono ancora stati elaborati vengono eliminati.

Se l'elaborazione in un metodo non riesce, questo viene indicato nel valore della proprietà Result. Il valore di Result deve essere verificato dopo ogni chiamata di un metodo. Il risultato può essere reimpostato a Ok utilizzando il metodo ResetResult.

NOTA: Tutti i metodi sono bloccati finché il valore della proprietà Result è diverso da Ok. Una chiamata di metodo in questo caso viene interrotta senza toccare le informazioni della proprietà Result.

Interfaccia

Il blocco funzione non ha ingressi e uscite. La funzionalità è disponibile attraverso i metodi e le proprietà. Per individuare disconnessioni dai client collegati, occorre chiamare ciclicamente il metodo CheckClients. In alternativa, è possibile recuperare il valore della proprietà NumberOfConnectedClients. Uno o l'altro possono verificare se i client sono ancora collegati oppure se hanno chiuso la connessione.

Esempio di implementazione

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;