Example for FbTcpServer_Multiconnect_base

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.

I connected FbTcpServerMulticonnect but I get an error whether Fb is enabled or not. I am attaching a screenshot.


Tell me what does unknown error mean?

I tried many different options but the connection could not be established. I suspect that the fb description is incorrect. The screenshot below shows that there is some kind of address. But there is no address on FB itself.

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.

1 Like

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.

1 Like

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

1 Like

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.

1 Like