FB_LocalClient

Bei gesetztem bEnable-Eingang wird immer wieder versucht, nach Ablauf der CLIENT_RECONNECT_TIME, die Verbindung zum Remote-Server herzustellen. Der Remote-Server wird über die sRemoteHost-IP Adresse und die nRemotePort-IP Portadresse identifiziert. Der Datenaustausch zum Server wurde in einem separaten Funktionsbaustein FB_ClientDataExcha gekapselt. Der Datenaustausch erfolgt zyklisch, immer nach Ablauf von PLCPRJ_SEND_CYCLE_TIME. Dabei wird die sToServer-Stringvariable zum Server gesendet, der vom Server zurückgesandte String steht am Ausgang sFormServer zur Verfügung. Eine andere Implementierung, in der der Remote-Server bei Bedarf angesprochen wird, ist aber ebenfalls möglich. Bei einem Fehler wird die vorhandene Verbindung geschlossen und eine neue aufgebaut.
Schnittstelle
FUNCTION_BLOCK FB_LocalClient
VAR_INPUT
sRemoteHost : STRING(15) := '127.0.0.1';(* IP adress of remote server *)
nRemotePort : UDINT := 0;
sToServer : T_MaxString:= 'TEST';
bEnable : BOOL;
END_VAR
VAR_OUTPUT
bConnected : BOOL;
hSocket : T_HSOCKET;
bBusy : BOOL;
bError : BOOL;
nErrId : UDINT;
sFromServer : T_MaxString;
END_VAR
VAR
fbConnect : FB_SocketConnect := ( sSrvNetId := '' );
fbClose : FB_SocketClose := ( sSrvNetId := '', tTimeout := DEFAULT_ADS_TIMEOUT );
fbClientDataExcha : FB_ClientDataExcha;
fbConnectTON : TON := ( PT := PLCPRJ_RECONNECT_TIME );
fbDataExchaTON : TON := ( PT := PLCPRJ_SEND_CYCLE_TIME );
eStep : E_ClientSteps;
END_VAR
Realisierung
CASE eStep OF
CLIENT_STATE_IDLE:
IF bEnable XOR bConnected THEN
bBusy := TRUE;
bError := FALSE;
nErrid := 0;
sFromServer := '';
IF bEnable THEN
fbConnectTON( IN := FALSE );
eStep := CLIENT_STATE_CONNECT_START;
ELSE
eStep := CLIENT_STATE_CLOSE_START;
END_IF
ELSIF bConnected THEN
fbDataExchaTON( IN := FALSE );
eStep := CLIENT_STATE_DATAEXCHA_START;
ELSE
bBusy := FALSE;
END_IF
CLIENT_STATE_CONNECT_START:
fbConnectTON( IN := TRUE, PT := PLCPRJ_RECONNECT_TIME );
IF fbConnectTON.Q THEN
fbConnectTON( IN := FALSE );
fbConnect( bExecute := FALSE );
fbConnect(sRemoteHost := sRemoteHost,
nRemotePort := nRemotePort,
bExecute := TRUE );
eStep := CLIENT_STATE_CONNECT_WAIT;
END_IF
CLIENT_STATE_CONNECT_WAIT:
fbConnect( bExecute := FALSE );
IF NOT fbConnect.bBusy THEN
IF NOT fbConnect.bError THEN
bConnected := TRUE;
hSocket := fbConnect.hSocket;
eStep := CLIENT_STATE_IDLE;
LogMessage( 'LOCAL client CONNECTED!', hSocket );
ELSE
LogError( 'FB_SocketConnect', fbConnect.nErrId );
nErrId := fbConnect.nErrId;
eStep := CLIENT_STATE_ERROR;
END_IF
END_IF
CLIENT_STATE_DATAEXCHA_START:
fbDataExchaTON( IN := TRUE, PT := PLCPRJ_SEND_CYCLE_TIME );
IF fbDataExchaTON.Q THEN
fbDataExchaTON( IN := FALSE );
fbClientDataExcha( bExecute := FALSE );
fbClientDataExcha( hSocket := hSocket,
sToServer := sToServer,
bExecute := TRUE );
eStep := CLIENT_STATE_DATAEXCHA_WAIT;
END_IF
CLIENT_STATE_DATAEXCHA_WAIT:
fbClientDataExcha( bExecute := FALSE );
IF NOT fbClientDataExcha.bBusy THEN
IF NOT fbClientDataExcha.bError THEN
sFromServer := fbClientDataExcha.sFromServer;
eStep := CLIENT_STATE_IDLE;
ELSE
(* possible errors are logged inside of fbClientDataExcha function block *)
nErrId := fbClientDataExcha.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( 'LOCAL client CLOSED!', hSocket );
bConnected := FALSE;
MEMSET( ADR(hSocket), 0, SIZEOF(hSocket));
IF fbClose.bError THEN
LogError( 'FB_SocketClose (local 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: (* Error step *)
bError := TRUE;
IF bConnected THEN
eStep := CLIENT_STATE_CLOSE_START;
ELSE
bBusy := FALSE;
eStep := CLIENT_STATE_IDLE;
END_IF
END_CASE