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!
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?