Connect PFC200 via UDP with random port

Hi,

I have to connect to another system by using UDP protocol but the port that used to connect is randomly and generated by another system. When I connected, the PFC200 need to use the port follow port number that generated from another system. How can I find the port number or how to scan the port which one is opened.

Thank you.

Hello, how can you know what port is for what communication ?
If your device A has a UDP server which port is random, i don’t think there is a possibility to find this port without having to test / scan all port and this can take a long time.
Another possibility is the device A send to the PFC on a known UDP port his opened port number so the PFC can connect to it.

I captured the message via wireshark and find out, the device A will random the source port and need the PFC send message back at the same port. but the destination port is fixed at port 44045.
And the number of source port will send via UDP message but I used the UDP NBS library it show only the data, i not found the message of port number for source port.

You will need to set the fix destination port in codesys like 5000. Then you need to write the code for dynamicly accept all incoming requests via udp ip and port address. Maybe you can find a basic example which created with node-red and also you can do it in codesys as well. The thing that ı have mentioned is like that;

(Receive UDP data from any sender)
IF Error = 0 THEN
BytesReceived := SysSockRecvFrom(UdpSocket, ADR(ReceiveBuffer), SIZEOF(ReceiveBuffer), 0, ADR(ClientAddr));

IF BytesReceived > 0 THEN
    (ClientAddr now contains the sender's IP and dynamic port)
    
    (* Step 5: Send response to the sender *)
    BytesSent := SysSockSendTo(UdpSocket, ADR(SendBuffer), SIZEOF(SendBuffer), 0, ADR(ClientAddr));
END_IF

END_IF;

Hi
I try but it not working, i try to send a UDP data from device A and PFC still not received.

PROGRAM POU_3
VAR
	xstart:BOOL;
	BytesReceived:	__XINT;
	BytesSent:	__XINT;
	UdpSocket:syssocket_interfaces.RTS_IEC_HANDLE;
	ReceiveBuffer:ARRAY[0..255]OF BYTE:=[];
	SendBuffer:ARRAY[0..255]OF BYTE:=[];
	ClientAddr:syssocket_interfaces.SOCKADDRESS;
	Recv_data:syssocket_interfaces.RTS_IEC_RESULT;
	send_data:syssocket_interfaces.RTS_IEC_RESULT;
	wPort:WORD;
	sclientaddr:STRING;
END_VAR

syssocket.SysSockInetAddr (sclientaddr, ADR(ClientAddr.sin_addr));
ClientAddr.sin_family := syssocket.socket_af_inet;
ClientAddr.sin_port:=syssocket.syssockHtons(wPort);


//received data
IF xstart THEN
	BytesReceived := SysSockRecvFrom(UdpSocket, ADR(ReceiveBuffer), SIZEOF(ReceiveBuffer), 0, ADR(ClientAddr),SIZEOF(ClientAddr),Recv_data);
	
	IF BytesReceived > 0 THEN
    (*ClientAddr now contains the sender's IP and dynamic port*)
    
//send data
    BytesSent := SysSockSendTo(UdpSocket, ADR(SendBuffer), SIZEOF(SendBuffer), 0, ADR(ClientAddr),SIZEOF(ClientAddr),send_data);
END_IF
END_IF

You might think about trying Node Red running on the PFC to receive the port number from Device A. Then you can use NVL’s to get the UDP port number into the Codesys runtime.

Hello, If you are using the NBS library (NetBaseSrv) here is a sample:

VAR_INPUT
	xOpen						: BOOL; // Enable the server
	sIpAddress					: STRING := '0.0.0.0'; // Server IP Address (Only needed if you want to force the server on a network card, let '0.0.0.0' to enable the server on all available network cards)
	uiPort						: UINT := 44045; // Server Port Number
END_VAR
VAR
	_oUDP_Peer					: NBS.UDP_Peer;
		_xEnable_Server			: BOOL;
		_xBusy_Server			: BOOL;
		_xError_Server			: BOOL;
		_eErrorID_Server			: NBS.ERROR;
		//_itfAsyncProperty			: NBS.IAsyncProperty;
		_oIPv4Address			: NBS.IPv4Address;
		_uiPort					: UINT;
		_xActive_Server			: BOOL;
		//_itfMulticast				: NBS.IIPAddressSet;
		_itfPeer					: NBS.IPeer;
		
	// IP-Address of Producer_Device is set via Receive2 method
	_abBuffer_Read				: ARRAY [0..1500] OF BYTE;
	_udiCount_Read				: UDINT;
	_eErrorID_Read				: NBS.ERROR;
    _oIPv4ClientAddress				: NBS.IPv4Address;
    _itfIPAddressFrom				: NBS.IIPAddress := _oIPv4ClientAddress;
	_uiClientPort					: UINT;
	
	xRead						: BOOL;
	_sIPv4ClientAddress			: NBS.IPADDRESS;
	_uiReadClientPort				: UINT;
	
	_udiFrameLengh				: UDINT := 48;
	
	_xWrite						: BOOL;
	_abBuffer_Write				: ARRAY [0..1500] OF BYTE;
	_udiSize_Write				: UDINT;
	_udiCount_Write				: UDINT;
	_eErrorID_Write				: NBS.ERROR;
_oUDP_Peer(
	xEnable				:= _xEnable_Server, 
	xBusy				=> _xBusy_Server, 
	xError				=> _xError_Server, 
	eErrorID			=> _eErrorID_Server, 
	itfIPAddress		:= _oIPv4Address, 
	uiPort				:= _uiPort, 
	xActive				=> _xActive_Server, 
	itfPeer				=> _itfPeer
);

IF NOT(xOpen) THEN
	_xEnable_Server := FALSE;
ELSE
	IF ((_xError_Server) OR (uiPort <> _uiPort) OR (sIpAddress <> _oIPv4Address.ipAddress)) AND (_xEnable_Server) THEN
		_xEnable_Server := FALSE;
	ELSIF NOT(_xEnable_Server) THEN
		_xEnable_Server := TRUE;
		_uiPort := uiPort;
		
		_oIPv4Address.ipAddress := sIpAddress;
	ELSE
		IF (_xActive_Server) THEN
			// Receive the data, if no data is received eError is PENDING
			_eErrorID_Read := _oUDP_Peer.Receive(
				pData				:= ADR(_abBuffer_Read), 
				udiSize				:= SIZEOF(_abBuffer_Read), 
				itfIPAddressFrom	:= _itfIPAddressFrom, 
				uiPortFrom			=> _uiClientPort, 
				udiCount			=> _udiCount_Read
			);
			IF (_eErrorID_Read = 0) AND (_udiCount_Read >= _udiFrameLengh) THEN
				
				_sIPv4ClientAddress := _oIPv4ClientAddress.ipAddress;
				_uiReadClientPort := _uiClientPort;
				
				/// Start protocol \\\
				_abBuffer_Write[0] := ???;
				_abBuffer_Write[1] := ???;
				_abBuffer_Write[2] := ???;
				_abBuffer_Write[3] := ???;
						
				_udiSize_Write := 4;
						
				_xWrite := TRUE;
				/// End protocol \\\
				
				IF _xWrite THEN
					// Sending data back to itfIPAddress, in this case the Producer_Device myIPProducer
					_eErrorID_Write := _oUDP_Peer.Send(
						itfIPAddress	:= _oIPv4ClientAddress, 
						uiPort			:= _uiClientPort, 
						pData			:= ADR(_abBuffer_Write), 
						udiSize			:= _udiSize_Write, 
						udiCount		=> _udiCount_Write
					);
					_xWrite := FALSE;
				END_IF;
			END_IF;
		END_IF;
	END_IF;
END_IF;

This should work.