FB_LocalClient
Here you can unpack the complete source for the client project: Example 1: Client;
If the bEnable input is set, the system will keep trying to establish the connection to the remote server once the PLCPRJ_RECONNECT_TIME has elapsed. The remote server is identified via the sRemoteHost IP address and the nRemotePort IP port address. The data exchange with the server was encapsulated in a separate function block (FB_ClientDataExcha). Data exchange is always cyclic once PLCPRJ_SEND_CYCLE_TIME has elapsed. The sToServer string variable is sent to the server, and the string sent back by the server is returned at output sFormServer. Another implementation, in which the remote server is addressed as required is also possible. In the event of an error, the existing connection is closed, and a new connection is established.
Interface
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
Implementation
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