AsTCP - Communication is terminated with error number 32609

I tried to use AsTCP Library to communicate B&R PLC with Siemens PLC and I get error number 32609 (The connection has been terminated by the other station). Can you guy tell me the reason why and how to fix it? Thank you very much.

Hi,

I can’t tell you, why the remote station terminates the connection.
But TCP is a connection oriented protocol and the channel has to be “consistent”, this is “supervised” by the TCP stack. And if one of the partners closes the connection for whatever reason, the other partner has to close too.
So, when getting the function block status 32609, you have to do on your side also a TcpClose and TcpOpen again to re-establish the TCP channel.

Best regards!

1 Like

We use LCom_Communication - Block from SIemens-Library on the SIemens-Side. And the connection will be stable.

On BuR-Side:
FUNCTION_BLOCK TCP_Send_Receive
CASE Client.Schritt OF
TCP_Idle:
IF Enable THEN
Client.Schritt := 1;
END_IF

	 TCP_Open: (* Open Ethernet Interface *)
		Client.FNC_TcpOpen.pIfAddr := 0;  (* Which Interface to open *)
		Client.FNC_TcpOpen.port := Port;  (* Port on client side to use *)
		Client.FNC_TcpOpen.options := 0;	
		Client.FNC_TcpOpen(enable := TRUE);  (* Call the Function *)
					
		IF Client.FNC_TcpOpen.status = 0 THEN  (* TcpOpen successfull *)
			Client.Schritt := TCP_IoCtrl;											
		ELSIF Client.FNC_TcpOpen.status = ERR_FUB_BUSY THEN  (* TcpOpen not finished -> redo *)				
		  (* Busy *)
		ELSE  (* Goto Error Step *)
			Client.Schritt := TCP_Error;
		END_IF
 
	 TCP_IoCtrl: 		 
	 	Client.Linger_Opt_typ.lLinger := 0; (* linger Time = 0 *)
		Client.Linger_Opt_typ.lOnOff := 1; (* linger Option ON *)
			 
		Client.FNC_TcpIoctl.ident := Client.FNC_TcpOpen.ident; (* Connection Ident from AsTP.TCP_Open *)
		Client.FNC_TcpIoctl.ioctl := tcpSO_LINGER_SET; (* Set Linger Options *)
		Client.FNC_TcpIoctl.pData := ADR(Client.Linger_Opt_typ);
		Client.FNC_TcpIoctl.datalen := SIZEOF(Client.Linger_Opt_typ);
	Client.FNC_TcpIoctl(enable := TRUE);	    
	
		IF Client.FNC_TcpIoctl.status = 0 THEN  (* TcpIoctl successfull *)
			Client.Schritt := TCP_Connect;											
		ELSIF Client.FNC_TcpIoctl.status = ERR_FUB_BUSY THEN  (* TcpIoctl not finished -> redo *)				
		  (* Busy *)
		ELSE  (* Goto Error Step *)
			Client.Schritt := TCP_Error;
		END_IF
	
	TCP_Connect: (* Connect to the other Station *)					
		Client.FNC_TcpClient.ident := Client.FNC_TcpOpen.ident;  (* Connection Ident from AsTCP.TCP_Open *)
		Client.FNC_TcpClient.portserv := Port;  (* Port on server side to use *)
		Client.FNC_TcpClient.pServer := ADR(IP_Adresse);  (* Server Address *)
		Client.FNC_TcpClient(enable := TRUE);  (* Call the Function*)
		
		IF Client.FNC_TcpClient.status = 0 THEN  (* Open ok -> Send Data *)
			Client.Schritt := TCP_Send;	
		ELSIF Client.FNC_TcpClient.status = ERR_FUB_BUSY THEN  (* TcpClient not finished -> redo *)	
		  (* Busy *)
		ELSIF Client.FNC_TcpClient.status = tcpERR_INVALID THEN  (* Port error -> Close actual connection, and reopen a new one *)
			Client.Schritt := TCP_Close;
		ELSE  (* Goto Error Step *)
			Client.Schritt := TCP_Error;
		END_IF
	
	TCP_Send: (* Send Data to the Server *)
		IF (SendBuffer = 0) OR (SendBufferLen = 0) THEN
    Client.Schritt := TCP_Receive;
  ELSE
    Client.FNC_TcpSend.ident := Client.FNC_TcpOpen.ident;  (* Connection Ident from AsTCP.TCP_Open *)
		  Client.FNC_TcpSend.pData := SendBuffer;  (* Which data to send *)
		  Client.FNC_TcpSend.datalen := SendBufferLen;  (* Lenght of data to send *)											
		  Client.FNC_TcpSend.flags := 0;
		  Client.FNC_TcpSend(enable := TRUE);  (* Call the Function*)
			
		  IF Client.FNC_TcpSend.status = ERR_OK THEN  (* Data was sent sucessfully -> receive data *)
      Client.Schritt := TCP_Receive;
		  ELSIF Client.FNC_TcpSend.status = ERR_FUB_BUSY THEN  (* TcpSend not finished -> redo *)	
		    (* Busy *)
		  ELSIF (Client.FNC_TcpSend.status = tcpERR_SENTLEN) OR (Client.FNC_TcpSend.status = tcpERR_NOT_CONNECTED) THEN (* Connection Lost *)
			  Client.Schritt := TCP_Close;
		  ELSE  (* Goto Error Step *)
			  Client.Schritt := TCP_Error;
		  END_IF				
		END_IF
	
    TCP_Receive: (* Receive Data from the Server *)
		  IF (ReceiveBuffer = 0) OR (ReceiveBufferLen = 0) THEN
		  IF Enable THEN
        Client.Schritt := TCP_Send;
      ELSE
        Client.Schritt := TCP_Close;
      END_IF
    ELSE
      Client.FNC_TcpRecv.ident := Client.FNC_TcpOpen.ident;  (* Connection Ident from AsTCP.TCP_Open *)
	  	  Client.FNC_TcpRecv.pData	:= ReceiveBuffer;  (* Where to store the incoming data *)
		    Client.FNC_TcpRecv.datamax := ReceiveBufferLen;  (* Lenght of data buffer *)
		    Client.FNC_TcpRecv.flags := 0;
		    Client.FNC_TcpRecv(enable := TRUE);  (* Call the Function*)

		  IF Client.FNC_TcpRecv.status = ERR_OK THEN  (* Data was received sucessfully -> Send next packet *)
  			  IF Enable THEN
          Client.Schritt := TCP_Send;
        ELSE
          Client.Schritt := TCP_Close;
        END_IF
	  		  Client.Rcv_Timeout := 0;
		    ELSIF Client.FNC_TcpRecv.status = tcpERR_NO_DATA THEN  (* No data received - wait *)
		      Client.Rcv_Timeout := Client.Rcv_Timeout + 1;
		      IF Client.Rcv_Timeout > TimeOut THEN
 		        Client.Schritt := TCP_Close;
			      Client.Rcv_Timeout := 0;
		      END_IF
		      (* No Data received *)
		    ELSIF Client.FNC_TcpRecv.status = ERR_FUB_BUSY THEN  (* TcpRecv not finished -> redo *)		
		      (* Busy *)
		    ELSIF Client.FNC_TcpSend.status = tcpERR_NOT_CONNECTED THEN (* Connection Lost *)			
			    Client.Schritt := TCP_Close;
		    ELSE  (* Goto Error Step *)
			    Client.Schritt := TCP_Error;
		    END_IF
	    END_IF
	TCP_Close: (* Close connection *)
		Client.FNC_TcpClose.ident := Client.FNC_TcpOpen.ident;  (* Connection Ident from AsTCP.TCP_Open *)
		Client.FNC_TcpClose.how := 0;
		Client.FNC_TcpClose(enable := TRUE);  (* Call the Function*)

		IF Client.FNC_TcpClose.status = 0 THEN  (* Close sucessfull -> Reopen the interface *)
			Client.Schritt := TCP_Idle;
		ELSIF Client.FNC_TcpClose.status = ERR_FUB_BUSY THEN  (* TcpClose not finished -> redo *)	
		  (* Busy *)
		ELSE  (* Goto Error Step *)
			Client.Schritt := TCP_Error;
		END_IF
	
   TCP_Error: (* Here some error Handling has to be implemented *)
		 Client.Schritt := TCP_Close;
END_CASE		

END_FUNCTION_BLOCK

Additional - Info:
Communication Library LCom for S7-1200/S7-1500

Libraries for Communication for SIMATIC Controllers - ID: 109780503 - Industry Support Siemens

Hi @Chanh_Le what is the status of your topic, can you update us and close it?