FB_RemoteClient

FB_RemoteClient 1:

Beim gesetzten bEnable-Eingang wird nach Ablauf der PLCPRJ_ACCEPT_POOLING_TIME versucht, die Verbindungsanforderung eines Remote-Clients anzunehmen (zu akzeptieren). Der Datenaustausch zum Remote-Client wurde in einem separaten Funktionsbaustein FB_ServerDataExcha gekapselt. Nach einem erfolgreichen Aufbau der Verbindung wird die Instanz vom FB_ServerDataExcha Funktionsbaustein aktiviert. Bei einem Fehler wird die angenommene Verbindung geschlossen und eine neue aufgebaut.

Interface

FUNCTION_BLOCK FB_RemoteClient
VAR_INPUT
    hListener               : T_HSOCKET;
    bEnable                 : BOOL;
END_VAR
VAR_OUTPUT
    bAccepted               : BOOL;
    hSocket                 : T_HSOCKET;
    bBusy               : BOOL;
    bError              : BOOL;
    nErrID              : UDINT;
    sFromClient             : T_MaxString;
END_VAR
VAR
    fbAccept                : FB_SocketAccept   := ( sSrvNetID := '', tTimeout := DEFAULT_ADS_TIMEOUT );
    fbClose                 : FB_SocketClose  := ( sSrvNetID := '', tTimeout := DEFAULT_ADS_TIMEOUT );
    fbServerDataExcha               : FB_ServerDataExcha;
    fbAcceptTON             : TON  := ( PT := PLCPRJ_ACCEPT_POLLING_TIME );
    eStep               : E_ClientSteps;
END_VAR

 

Implementierung

 

CASE eStep OF

    CLIENT_STATE_IDLE:
        IF bEnable XOR bAccepted THEN
            bBusy := TRUE;
            bError := FALSE;
            nErrId := 0;
            sFromClient := '';
            IF bEnable THEN
                fbAcceptTON( IN := FALSE );
                eStep := CLIENT_STATE_CONNECT_START;
            ELSE
                eStep := CLIENT_STATE_CLOSE_START;
            END_IF
        ELSIF bAccepted THEN
            eStep := CLIENT_STATE_DATAEXCHA_START;
        ELSE
            bBusy := FALSE;
        END_IF

    CLIENT_STATE_CONNECT_START:
        fbAcceptTON( IN := TRUE, PT := PLCPRJ_ACCEPT_POLLING_TIME );
        IF fbAcceptTON.Q THEN
            fbAcceptTON( IN := FALSE );
            fbAccept(  bExecute := FALSE  );
            fbAccept(       hListener := hListener,
                        bExecute:= TRUE );
            eStep := CLIENT_STATE_CONNECT_WAIT;
        END_IF

    CLIENT_STATE_CONNECT_WAIT:
        fbAccept( bExecute := FALSE );
        IF NOT fbAccept.bBusy THEN
            IF NOT fbAccept.bError THEN
                IF fbAccept.bAccepted THEN
                    bAccepted := TRUE;
                    hSocket := fbAccept.hSocket;
                    LogMessage( 'REMOTE client ACCEPTED!', hSocket );
                END_IF
                eStep := CLIENT_STATE_IDLE;
            ELSE
                LogError( 'FB_SocketAccept',  fbAccept.nErrId );
                nErrId := fbAccept.nErrId;
                eStep := CLIENT_STATE_ERROR;
            END_IF
        END_IF

    CLIENT_STATE_DATAEXCHA_START:
        fbServerDataExcha( bExecute := FALSE );
        fbServerDataExcha(      hSocket := hSocket,
                                bExecute := TRUE );
        eStep := CLIENT_STATE_DATAEXCHA_WAIT;

    CLIENT_STATE_DATAEXCHA_WAIT:
        fbServerDataExcha( bExecute := FALSE, sFromClient=>sFromClient );
        IF NOT fbServerDataExcha.bBusy THEN
            IF NOT fbServerDataExcha.bError THEN
                eStep := CLIENT_STATE_IDLE;
            ELSE
                (* possible errors are logged inside of fbServerDataExcha function block *)
                nErrId := fbServerDataExcha.nErrID;
                eStep := CLIENT_STATE_ERROR;
            END_IF
        END_IF

    CLIENT_STATE_CLOSE_START:
        fbClose( bExecute := FALSE );
        fbClose(    hSocket:= hSocket,
                bExecute:= TRUE );
        eStep := CLIENT_STATE_CLOSE_WAIT;

    CLIENT_STATE_CLOSE_WAIT:
        fbClose( bExecute := FALSE );
        IF NOT fbClose.bBusy THEN
            LogMessage( 'REMOTE client CLOSED!', hSocket );
            bAccepted := FALSE;
            MEMSET( ADR( hSocket ), 0, SIZEOF( hSocket ) );
            IF fbClose.bError THEN
                LogError( 'FB_SocketClose (remote client)', fbClose.nErrId );
                nErrId := fbClose.nErrId;
                eStep := CLIENT_STATE_ERROR;
            ELSE
                bBusy := FALSE;
                bError := FALSE;
                nErrId := 0;
                eStep := CLIENT_STATE_IDLE;
            END_IF
        END_IF

    CLIENT_STATE_ERROR:
        bError := TRUE;
        IF bAccepted THEN
            eStep := CLIENT_STATE_CLOSE_START;
        ELSE
            eStep := CLIENT_STATE_IDLE;
            bBusy := FALSE;
        END_IF

END_CASE