I had a TCP communication to do with some external Equipment, and it is working well, using the exemple provided in codesys help.
To make it easy, i'm using chained TCP_Server, TCP_Connection and TCP_Read (not TCP_ReadBuffer) as descripted in help.
But (yes there is a but) I face a strange behaviour when clients disconnects. TCP_Read block is outputing error before TCP_Connection detects normal/abnormal connection ending.
Is that normal behaviour ?
Regards,
dFx
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
dFx hat geschrieben:
Hello forum users,
I had a TCP communication to do with some external Equipment, and it is working well, using the exemple provided in codesys help.
To make it easy, i'm using chained TCP_Server, TCP_Connection and TCP_Read (not TCP_ReadBuffer) as descripted in help.
But (yes there is a but) I face a strange behaviour when clients disconnects. TCP_Read block is outputing error before TCP_Connection detects normal/abnormal connection ending.
Is that normal behaviour ?
Regards,
dFx
Hello,
try it to configurate the xEnable parameter of the TCP_Read Functionblock.
Example:
xEnable := sTcpClient.xActive AND NOT sSendMsg.Q AND NOT sTcpWrite.xBusy,
Best regards
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
//----------------------------------------------------------------------------------------//ServerCall//----------------------------------------------------------------------------------------TCP.fbTCP_Server_V2(  Enable        :=TRUE,  IPAddr        :=TCP.IPAddress,  Port        :=TCP.uiPort,  SendDataOrder    :=,  SendDataBuffer    :=TCP.abySendBuffer,  SendDataSize    :=TCP.udiSendSize,  IsActive      =>,  IsConnected      =>,  InError        =>,  ReceivedDataTrigger  =>,  ReceivedDataBuffer  =>,  ReceivedDataSize  =>,  SendDataDone    =>,  BlockState      =>,  LastErrorBlock    =>,  LastError      =>);
//TCPserverv2code//ManagesTCPserverwith1connectionwithR/WcapabilitiesFUNCTION_BLOCKTCPServer_FBVAR_INPUT
  Enable : BOOL :=FALSE; // Enable TCP server
  IPAddr : NBS.IP_ADDR :=STRUCT(sADDR :='0.0.0.0'); // IP-Address of the TCP server
  Port : UINT :=0; // port OF the TCP serverÂ
  SendDataOrder : BOOL :=FALSE; // Data send order (delayed till connection active)Â
  SendDataBuffer : ARRAY [1.._udiMaxComBuffer] OFBYTE; // Byte buffer containing data to be sentÂ
  SendDataSize : UDINT :=0; // Size of data to be sent END_VARVAR_OUTPUT
  IsActive : BOOL :=FALSE; // TCP Server block runningÂ
  IsConnected : BOOL :=FALSE; // TCP Client connectedÂ
  InError : BOOL :=FALSE; // Indicates that an error has occurred during operationÂ
  ReceivedDataTrigger : BOOL :=FALSE; // Raising edge indicating data received
  ReceivedDataBuffer : ARRAY [1.._udiMaxComBuffer] OFBYTE; // received data bufferÂ
  ReceivedDataSize : UDINT :=0; // Receive sizeÂ
  SendDataDone : BOOL :=FALSE; // Data was send correctly
  BlockState : TCPServerStatus_ENUM; // Litteral block status
  LastErrorBlock : TCPServerErrorBlock_ENUM; // Name of block raising last occured error
  LastError : NBS.ERROR; // Last occured error  END_VARVAR
  TCP_Server : NBS.TCP_Server; // TCP_Server block
  TCP_Connection : NBS.TCP_Connection; // TCP_Connection block (1 client can connect)
  TCP_Read : NBS.TCP_Read; // TCP_Read block (reads on first connection)
  TCP_Write : NBS.TCP_Write; // TCP_Write block (writes on first connection)
  _Enable : BOOL; // Internal Enable to handle restart on errors
  RWError : BOOL; // Error occured during Read or Write
  ErrorCounter : CAA.COUNT; // Internal error counter for debbug purposesEND_VARVARCONSTANT
  _udiMaxComBuffer : UDINT :=1500;END_VAR//AutorecoveryfromRWerrorIFEnableANDNOT_EnableTHEN
  _Enable :=TRUE;ELSE
  IFNOTEnableTHEN
    _Enable :=FALSE;
    ErrorCounter :=0;
    LastErrorBlock :=TCPServerErrorBlock_ENUM.NONE;
    LastError :=NBS.ERROR.NO_ERROR;
  END_IFEND_IF//read/WriteerroronpreviousscanRWError :=(
        TCP_Read.xErrorAND
        (TCP_Read.eError=NBS.ERROR.TCP_RECEIVE_ERROR)
      )OR
      (
        TCP_Write.xErrorAND
        (
          (TCP_Read.eError=NBS.ERROR.TCP_SEND_ERROR)OR
          (TCP_Read.eError=NBS.ERROR.TIME_OUT)
        )
      );//RWErrormanagementIFRWErrorANDEnableTHEN
  //Somethingwaswrongwithread/write
  //Resetfullblock
  _Enable :=FALSE;END_IF//TCPServer//Thisblockhandlethesocketopen/closeTCP_Server(
  xEnable:=_Enable,
  ipAddr:=IPAddr,
  uiPort:=Port,
  xDone=> ,
  xBusy=> ,
  xError=> ,Â
  eError=> ,
  hServer=>);//TCPConnection//Thisblockhandleclientconnection//Ifconnectionisproperlyclosed, xDoneisset//Thenrestartconnectionblocktowaitforanotherclient//RWErrorsmayneedconnectiontoberestart(clientdisconnectedimproperlyisnotdetectedfromTCP_ConnectionblockTCP_Connection(
  xEnable:=TCP_Server.xBusyAND(NOTTCP_Connection.xDone),
  xDone=> ,
  xBusy=> ,
  xError=> ,
  hServer:=TCP_Server.hServer,
  eError=> ,
  xActive=> ,
  hConnection=>);//TCPRead//ThisblockallowstolistenfordataonopenedsocketTCP_Read(
  xEnable:=TCP_Connection.xActive,
  xDone=> ,
  xBusy=> ,
  xError=> ,
  hConnection:=TCP_Connection.hConnection,
  szSize:=_udiMaxComBuffer,
  pData:=ADR(ReceivedDataBuffer),
  eError=> ,
  xReady=>ReceivedDataTrigger,
  szCount=>ReceivedDataSize);//TCPWrite//ThisblockallowstosenddataonopenedsocketTCP_Write(
  xExecute:=SendDataOrder,
  udiTimeOut:=500000, // µs->500ms
  hConnection:=TCP_Connection.hConnection,
  szSize:=SendDataSize,
  pData:=ADR(SendDataBuffer),
  xDone=>SendDataDone,
  xBusy=> ,
  xError=> ,
  eError=>);//Genericerrormanagement//SavelasterrorIFTCP_Server.xErrorTHEN
  ErrorCounter :=ErrorCounter+1;
  LastError :=TCP_Server.eError;
  LastErrorBlock :=TCPServerErrorBlock_ENUM.SERVER;ELSE
  IFTCP_Connection.xErrorTHEN
    ErrorCounter :=ErrorCounter+1;
    LastError :=TCP_Connection.eError;
    LastErrorBlock :=TCPServerErrorBlock_ENUM.CONNECTION;
  ELSE
    IFTCP_Read.xErrorTHEN
      ErrorCounter :=ErrorCounter+1;
      LastError :=TCP_Read.eError;
      LastErrorBlock :=TCPServerErrorBlock_ENUM.READ;
    ELSE
      IFTCP_Write.xErrorTHEN
        ErrorCounter :=ErrorCounter+1;
        LastError :=TCP_Write.eError;
        LastErrorBlock :=TCPServerErrorBlock_ENUM.WRITE;
      END_IF
    END_IF
  END_IFEND_IF//outputsIsConnected :=TCP_Connection.xActive;IsActive :=TCP_Server.xBusy;InError :=TCP_Server.xError;//BlockstatusIFNOT_EnableTHEN
  BlockState :=TCPServerStatus_ENUM.DISABLED;ELSE
  IF_EnableANDNOTIsActiveTHEN
    BlockState :=TCPServerStatus_ENUM.SERVER_INIT;
  ELSE
    IFIsActiveANDNOTIsConnectedTHEN
      BlockState :=TCPServerStatus_ENUM.WAIT_CONNECTION;
    ELSE
      IFIsConnectedANDReceivedDataTrigger THEN
        BlockState :=TCPServerStatus_ENUM.DATA_RECEIVED;
      ELSE
        IFIsConnectedANDNOTSendDataOrderTHEN
          BlockState :=TCPServerStatus_ENUM.CLIENT_CONNECTED;
        ELSE
          IFIsConnectedANDSendDataOrderTHEN
            BlockState :=TCPServerStatus_ENUM.DATA_WRITTEN;
          END_IF
        END_IF
      END_IF
    END_IF
  END_IFEND_IF
EDIT : I also face another linked problem when using a switch : When my PC is connected as TCP client via a switch, and I disconnect my cable from the switch, there is no TCP error outputed. Even writing ends ok ...
Writing isn't the usual method to detect a down link on a tcp connection ?
To face this, I ping my Partner which is not very reliable (need to know Partner IP address). I do it outside the block, and then I reset Enable flag.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2018-03-08
Originally created by: luciano.assirelli
dFx hat geschrieben:
Hello forum users,
I had a TCP communication to do with some external Equipment, and it is working well, using the exemple provided in codesys help.
To make it easy, i'm using chained TCP_Server, TCP_Connection and TCP_Read (not TCP_ReadBuffer) as descripted in help.
But (yes there is a but) I face a strange behaviour when clients disconnects. TCP_Read block is outputing error before TCP_Connection detects normal/abnormal connection ending.
Is that normal behaviour ?
Regards,
dFx
Hi all, and thanks for existing.
I'm apparently facing the same problem. I need to implement a server accepting a single client.
To simplify things at the beginning, I implemented a simple echo server, which TCP_Writes the same
buffer contents, as soon as some contents arrives thru TCP_Read. And everything looks ok:
once the connection is established, echo is working.
Things get complcated when I "close" the connection, either from the client or server side: before reconnect,
the connection handle is properly at zero; after reconnect, the connection handle provided by the
TCP_Connection function block appears to be the same as before disconnect; and this is may not
be a problem, but the TCP_Read executed on that handle gives a permanent TCP_RECEIVE_ERROR (6012).
I have no other options than disable/enable the TCP_Server fb, but nothing changes. By the way, even if
this worked, I suppose that it would be not applicable if one had to implement a multiple client solution.
The only operation that really reset things is a controller warm reset.
Just to put some other meat on the grill... I have been using a proprietary TCP server implementation
from ELAU (now Schneider Electric), and it gave me the option to filter incoming connection based on the IP address.
How could this be done with CAA netbase? Or, more simply spelled: how can I obtain the IP address of an incoming connection?
I will really appreciate any comments!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm implementing a TCP read write but is quit hard to get it operational. I'm working with Somachine (Codesys environment for Schneider Electric PLC's), In the example from the CAA Net base services is a 'Createmessage fb. I'm not retrieving this in the libs that i have installed. Can someone tell me where to find it?
gr Tom
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
luciano.assirelli hat geschrieben:
Things get complcated when I "close" the connection, either from the client or server side: before reconnect,
the connection handle is properly at zero; after reconnect, the connection handle provided by the
TCP_Connection function block appears to be the same as before disconnect; and this is may not
be a problem, but the TCP_Read executed on that handle gives a permanent TCP_RECEIVE_ERROR (6012).
I have no other options than disable/enable the TCP_Server fb, but nothing changes. By the way, even if
this worked, I suppose that it would be not applicable if one had to implement a multiple client solution.
The only operation that really reset things is a controller warm reset.
HI,
I have the same problem. Did you find some solution please?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
dFx hat geschrieben:
To face this, I ping my Partner which is not very reliable (need to know Partner IP address). I do it outside the block, and then I reset Enable flag.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2019-07-18
Originally created by: rettore84
luciano.assirelli hat geschrieben:
Hi all, and thanks for existing.
I'm apparently facing the same problem. I need to implement a server accepting a single client.
To simplify things at the beginning, I implemented a simple echo server, which TCP_Writes the same
buffer contents, as soon as some contents arrives thru TCP_Read. And everything looks ok:
once the connection is established, echo is working.
Things get complcated when I "close" the connection, either from the client or server side: before reconnect,
the connection handle is properly at zero; after reconnect, the connection handle provided by the
TCP_Connection function block appears to be the same as before disconnect; and this is may not
be a problem, but the TCP_Read executed on that handle gives a permanent TCP_RECEIVE_ERROR (6012).
I have no other options than disable/enable the TCP_Server fb, but nothing changes. By the way, even if
this worked, I suppose that it would be not applicable if one had to implement a multiple client solution.
The only operation that really reset things is a controller warm reset.
Just to put some other meat on the grill... I have been using a proprietary TCP server implementation
from ELAU (now Schneider Electric), and it gave me the option to filter incoming connection based on the IP address.
How could this be done with CAA netbase? Or, more simply spelled: how can I obtain the IP address of an incoming connection?
I will really appreciate any comments!
Not sure if someone is still having issues with this and getting error 6012. This was happening whenever the client was disconnecting from Codesys Server. I had always to do a warm/cold restart. My solution was not to use the Handler FB that comes in the example project. Take all the logic that it is inside the Handler FB, and put it outside. You don't need the Handler FB. It will work.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I also have this problem. I am using code similar to what dFx posted, not like the example with the
Handler FB, and for a single client it works fine resetting the server each time the client disconnects.
Luckily, I only need a server for one client in my current application.
I cannot find anything documenting what causes a TCP_RECEIVE_ERROR (6012).
It surely does not mean that a message was not received correctly, because the messages always come
through correctly.
The error is raised if I physically disconnect the server from the network, but also when the client closes
the connection correctly by setting the TCP FIN flag. I have checked with Wireshark that a full normal
handshake for closing the connection is performed, but still get the error.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have a project that was compiled on an old version of codesys. I recently upgraded my entire project to use all latest library and bumped into the same error (6012).
My problem is even worse, as on newer versions of the library (3.5.12.0/3.5.15.0) I don't even receive data from the network.
My temporary solution was to downgrade only the NBS library to an older version - that seemed to solve my issue. I've gone back to version 3.5.6.0 of the library.
Can anyone from codesys comment on this?
Last edit: maoravni 2020-05-05
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've been struggling with this too. To defeat the Tcp_Read/Write error, I cleared my Tx and Rx (send and receive) buffers every cycle. I guess this makes sense, since overwriting a larger message with a small one without clearing first would be...messy.
I have large sized arrays (65,500 bytes), so I had to use the following method to zero out all my arrays without hitting a watchdog timer exception:
Hello forum users,
I had a TCP communication to do with some external Equipment, and it is working well, using the exemple provided in codesys help.
To make it easy, i'm using chained TCP_Server, TCP_Connection and TCP_Read (not TCP_ReadBuffer) as descripted in help.
But (yes there is a but) I face a strange behaviour when clients disconnects. TCP_Read block is outputing error before TCP_Connection detects normal/abnormal connection ending.
Is that normal behaviour ?
Regards,
dFx
Hello,
try it to configurate the xEnable parameter of the TCP_Read Functionblock.
Example:
xEnable := sTcpClient.xActive AND NOT sSendMsg.Q AND NOT sTcpWrite.xBusy,
Best regards
Thanks for your reply @Basta87
I don't see any reference about sequencing Read/Write in the NBS manual.
Anyway, I will try it on site and report the result as soon as possible.
This is my call order for NBS function blocks:
Can you post the complete call of the function blocks?
Hope this will help :
EDIT : I also face another linked problem when using a switch : When my PC is connected as TCP client via a switch, and I disconnect my cable from the switch, there is no TCP error outputed. Even writing ends ok ...
Writing isn't the usual method to detect a down link on a tcp connection ?
To face this, I ping my Partner which is not very reliable (need to know Partner IP address). I do it outside the block, and then I reset Enable flag.
Originally created by: luciano.assirelli
Hi all, and thanks for existing.
I'm apparently facing the same problem. I need to implement a server accepting a single client.
To simplify things at the beginning, I implemented a simple echo server, which TCP_Writes the same
buffer contents, as soon as some contents arrives thru TCP_Read. And everything looks ok:
once the connection is established, echo is working.
Things get complcated when I "close" the connection, either from the client or server side: before reconnect,
the connection handle is properly at zero; after reconnect, the connection handle provided by the
TCP_Connection function block appears to be the same as before disconnect; and this is may not
be a problem, but the TCP_Read executed on that handle gives a permanent TCP_RECEIVE_ERROR (6012).
I have no other options than disable/enable the TCP_Server fb, but nothing changes. By the way, even if
this worked, I suppose that it would be not applicable if one had to implement a multiple client solution.
The only operation that really reset things is a controller warm reset.
Just to put some other meat on the grill... I have been using a proprietary TCP server implementation
from ELAU (now Schneider Electric), and it gave me the option to filter incoming connection based on the IP address.
How could this be done with CAA netbase? Or, more simply spelled: how can I obtain the IP address of an incoming connection?
I will really appreciate any comments!
hi Everyone !
I'm implementing a TCP read write but is quit hard to get it operational. I'm working with Somachine (Codesys environment for Schneider Electric PLC's), In the example from the CAA Net base services is a 'Createmessage fb. I'm not retrieving this in the libs that i have installed. Can someone tell me where to find it?
gr Tom
Create message is an exemple of user function that transfert the data into your buffer.
HI,
I have the same problem. Did you find some solution please?
Originally created by: rettore84
Not sure if someone is still having issues with this and getting error 6012. This was happening whenever the client was disconnecting from Codesys Server. I had always to do a warm/cold restart. My solution was not to use the Handler FB that comes in the example project. Take all the logic that it is inside the Handler FB, and put it outside. You don't need the Handler FB. It will work.
I also have this problem. I am using code similar to what dFx posted, not like the example with the
Handler FB, and for a single client it works fine resetting the server each time the client disconnects.
Luckily, I only need a server for one client in my current application.
I cannot find anything documenting what causes a TCP_RECEIVE_ERROR (6012).
It surely does not mean that a message was not received correctly, because the messages always come
through correctly.
The error is raised if I physically disconnect the server from the network, but also when the client closes
the connection correctly by setting the TCP FIN flag. I have checked with Wireshark that a full normal
handshake for closing the connection is performed, but still get the error.
I have the same problem as well. Did anyone find some solution please?
I have a project that was compiled on an old version of codesys. I recently upgraded my entire project to use all latest library and bumped into the same error (6012).
My problem is even worse, as on newer versions of the library (3.5.12.0/3.5.15.0) I don't even receive data from the network.
My temporary solution was to downgrade only the NBS library to an older version - that seemed to solve my issue. I've gone back to version 3.5.6.0 of the library.
Can anyone from codesys comment on this?
Last edit: maoravni 2020-05-05
Hey guys!
I've been struggling with this too. To defeat the Tcp_Read/Write error, I cleared my Tx and Rx (send and receive) buffers every cycle. I guess this makes sense, since overwriting a larger message with a small one without clearing first would be...messy.
I have large sized arrays (65,500 bytes), so I had to use the following method to zero out all my arrays without hitting a watchdog timer exception:
Mem.MemFill(pMemoryBlock:= ADR(arrRx),uiLength := SIZEOF(arrRx),byFillValue := 0);
Mem.MemFill(pMemoryBlock:= ADR(arrTx),uiLength := SIZEOF(arrTx),byFillValue := 0);
Hope this helps!
Is there a was to flush the TCP port before a TCP Read?
Last edit: masmith1553 2022-12-20