I’m trying to configure FbTcpServer_Multiconnect_base in order to receive several connections at the same time. Please help me with an example. How can I use this Fb in ST language.
I couldn’t figure it out right away from the documentation.
Hello Thomas, have you been able to have it worked ?
Unfortunately, no. Tried different options, unsuccessful.
You can look at using Node-RED with the TCP In and Out nodes. I found this to be a simpler solution to make TCP connections to multiple devices. The TCP In node provides a Session ID when a connection is made and was able to track connections this way.
I then used Network Variables to pass information to/from CODESYS.
Hope this helps!
Here is a sample I am using for different small TCP servers:
PROGRAM FbTCP_SERVER_MULTI
VAR_INPUT
xServer_Open : BOOL;
sServer_IpAddress : STRING := '0.0.0.0';
uiServer_Port : UINT := 502; // Server Port Number
tTCP_TimeOut : TIME := T#30S; // Timeout between each request data fragment after the first data fragment is received. The default value is 30 seconds.
END_VAR
VAR CONSTANT
MAX_SOCKET : BYTE := 15;
MAX_TCP_SERVER_SEND : DWORD := 1500;
MAX_TCP_SERVER_RECEIVE : DWORD := 3000;
MAX_TCP_SERVER_RECEIVE_SOCKET : DWORD := 1500;
END_VAR
VAR
_oTCP_Server : NBS.TCP_Server;
_xEnable_Server : BOOL;
_xBusy_Server : BOOL;
_xError_Server : BOOL;
_eErrorID_Server : NBS.ERROR;
_udiMaxConnections : UDINT;
//_itfAsyncProperty : NBS.IAsyncProperty;
//_oAsyncProperty : NBS.AsyncProperty;
//_itfTLSContext : NBS.ITLSContext;
//_oTLSContext : NBS.TLSContext := (sUseCaseName := 'NBSClient', ePurpose := NBS.PURPOSE.CLIENT_SIDE, sTLSVersion := '1.2', sHostname := 'wago-tcp-client', ciCertInfo := ciCertInfo);
//_itfTSNContext : NBS.ITSNContext;
//_itfIPAddress : NBS.IIPAddress;
_oIPv4Address : NBS.IPv4Address;
_uiPort : UINT;
_xActive_Server : BOOL;
_itfServer : NBS.IServer;
_iWorkerIndex : INT;
_usiActive : USINT;
_aoTCP_Connection : ARRAY [1..MAX_SOCKET] OF NBS.TCP_Connection;
_axEnable : ARRAY [1..MAX_SOCKET] OF BOOL;
_axDone : ARRAY [1..MAX_SOCKET] OF BOOL;
_axBusy : ARRAY [1..MAX_SOCKET] OF BOOL;
_axError : ARRAY [1..MAX_SOCKET] OF BOOL;
_aeErrorID : ARRAY [1..MAX_SOCKET] OF NBS.ERROR;
_axActive : ARRAY [1..MAX_SOCKET] OF BOOL;
_aitfConnection : ARRAY [1..MAX_SOCKET] OF NBS.IConnection;
_aabBuffer_Read : ARRAY [1..MAX_SOCKET] OF ARRAY [0..MAX_TCP_SERVER_RECEIVE_SOCKET] OF BYTE;
_audiCount_Read : ARRAY [1..MAX_SOCKET] OF UDINT;
_aeErrorID_Read : NBS.ERROR;
_aabBuffer_Write : ARRAY [1..MAX_SOCKET] OF ARRAY [0..MAX_TCP_SERVER_SEND] OF BYTE;
_audiSize_Write : ARRAY [1..MAX_SOCKET] OF UDINT;
_audiCount_Write : ARRAY [1..MAX_SOCKET] OF UDINT;
_aeErrorID_Write : NBS.ERROR;
_udiTCP_RxIndex : UDINT;
_xRxTrigger : BOOL;
_aoTCP_TimeOut : ARRAY [1..MAX_SOCKET] OF TON;
_xTxTrigger : BOOL;
END_VAR
_oTCP_Server(
xEnable := _xEnable_Server,
xBusy => _xBusy_Server,
xError => _xError_Server,
eErrorID => _eErrorID_Server,
udiMaxConnections := MAX_SOCKET,
//itfAsyncProperty := _itfAsyncProperty,
//itfTLSContext := _itfTLSContext,
//itfTSNContext := _itfTSNContext,
itfIPAddress := _oIPv4Address,
uiPort := _uiPort,
xActive => _xActive_Server,
itfServer => _itfServer
);
IF NOT(xServer_Open) THEN
_xEnable_Server := FALSE;
ELSE
IF ((_xError_Server) OR (uiServer_Port <> _uiPort) OR (sServer_IpAddress <> _oIPv4Address.ipAddress)) AND (_xEnable_Server) THEN
_xEnable_Server := FALSE;
ELSIF NOT(_xEnable_Server) THEN
_xEnable_Server := TRUE;
_uiPort := uiServer_Port;
_oIPv4Address.ipAddress := sServer_IpAddress;
ELSE
_usiActive := 0;
FOR _iWorkerIndex := 1 TO MAX_SOCKET BY 1 DO
_aoTCP_Connection[_iWorkerIndex](
xEnable := _axEnable[_iWorkerIndex],
xDone => _axDone[_iWorkerIndex],
xBusy => _axBusy[_iWorkerIndex],
xError => _axError[_iWorkerIndex],
eErrorID => _aeErrorID[_iWorkerIndex],
itfServer := _itfServer,
xActive => _axActive[_iWorkerIndex],
itfConnection => _aitfConnection[_iWorkerIndex]
);
IF _axDone[_iWorkerIndex] THEN
_aoTCP_TimeOut[_iWorkerIndex](IN := FALSE, PT := tTCP_TimeOut);
_axEnable[_iWorkerIndex] := FALSE;
ELSIF (_xActive_Server) THEN
_axEnable[_iWorkerIndex] := TRUE;
END_IF;
IF (_aoTCP_Connection[_iWorkerIndex].xActive) THEN
_usiActive := _usiActive + 1;
_aeErrorID_Read[_iWorkerIndex] := _aoTCP_Connection[_iWorkerIndex].Read(
pData:= ADR(_aabBuffer_Read[_iWorkerIndex]),
udiSize:= SIZEOF(_aabBuffer_Read[_iWorkerIndex]),
udiCount=> _audiCount_Read[_iWorkerIndex]
);
_aoTCP_TimeOut[_iWorkerIndex](IN := (_audiCount_Read[_iWorkerIndex] = 0) AND (_axActive[_iWorkerIndex]), PT := tTCP_TimeOut);
IF _aoTCP_TimeOut[_iWorkerIndex].Q THEN
_aoTCP_TimeOut[_iWorkerIndex](IN := FALSE, PT := tTCP_TimeOut);
_axEnable[_iWorkerIndex] := FALSE;
END_IF;
IF _aeErrorID_Read[_iWorkerIndex] = 0 AND _audiCount_Read[_iWorkerIndex] > 0 THEN
_xRxTrigger := TRUE;
_audiCount_Read[_iWorkerIndex] := 0;
END_IF;
(**************************************************************************************)
(************************************ MODIFY HERE ************************************)
(**************************************************************************************)
(**************************************************************************************)
(********************************** END MODIFY HERE **********************************)
(**************************************************************************************)
IF _xTxTrigger THEN
_aeErrorID_Write[_iWorkerIndex] := _aoTCP_Connection[_iWorkerIndex].Write(
pData := ADR(_aabBuffer_Write[_iWorkerIndex]),
udiSize := _audiSize_Write[_iWorkerIndex],
udiCount => _audiCount_Write[_iWorkerIndex]
);
_xTxTrigger := FALSE;
END_IF;
ELSE
_aoTCP_TimeOut[_iWorkerIndex](IN := FALSE, PT := tTCP_TimeOut);
END_IF;
END_FOR;
_iWorkerIndex := 1;
END_IF;
END_IF;
Ps this sample is using the Net Base Service as library:
| Company: | 3S - Smart Software Solutions GmbH |
|---|---|
| Title: | Net Base Services |
| Version: | 3.5.19.20 |
| Categories: | Intern; Application |
| Namespace: | NBS |
| Author: | 3S - Smart Software Solutions GmbH |
| Placeholder: | NetBaseSrv |
Hope it will help.
Can you tell me how you pass information from NodeRed to CodeSys?
This is where I see a very different fb. I’ve found an example of this before. I was thinking of using wago.
I’ve been told you should use Net Base Services library in the future as WagoAppSocket won’t be maintained any more.
You can use TCP_Server FB, on which you can link several TCP_Connection FB.
Here is a link to a Flow and CODESYS project that a colleague created. It uses the node-red-contrib-nvl palette, and NetVars in CODESYS.
Node-Red-Examples/Network Variables at main · jabdelmalak/Node-Red-Examples · GitHub
Am I right, if I use TCP_Server I need to create several different fb for each user?
The code I send you allow up to 15 socket used at the same time.
it’s already tested and work fine.
I haven’t tested with SSL security yet.

