Skip to main content

Kollmorgen Support Network

KAS to receive data via TCP/IP connections | 23 Jul 2020 | |

KAS to receive data via TCP/IP connections

This article provides a simple example of receiving data via TCP. 

  1. Import the attached program.
  2. Set EN_CONNECTION=true

The KAS system now listens for TCP connections from a remote device.

When the connection is established the device can send strings to the KAS IDE.

// If EN_CONNECTION = 0, close the socket
// Set Port Number and Amount of Characters to receive with each call of TcpReceive
if not(EN_CONNECTION) then
   if mysocket<>0 then
      Inst_TcpClose(true,mysocket);
      Inst_TcpClose(false,mysocket);
      mysocket:=0;
   end_if;
   mycounter:=1;
   KAS_TCP_PORT:=1234;
   MAX_CHAR_TO_RECEIVE:=200;
   return;
end_if;

case mycounter of

1: //Create a Socket by perofrming an open and bond operation 
   Inst_TcpListen(true,KAS_TCP_PORT, 2(*DINT*) );
   mycounter := mycounter + 1;  

2: // Wait for function block completion and provide the ID for the Listening Socket
   Inst_TcpListen(true,KAS_TCP_PORT, 2(*DINT*) );
   if Inst_TcpListen.Done then
      Inst_TcpListen(false,1234, 2(*DINT*) );
      mycounter := mycounter + 1;
   end_if;

3: // Start function block to accept the Listening Client ID
   Inst_TcpAccept(true,Inst_TcpListen.ListenID);
   mycounter := mycounter + 1;

4: // Wait for function block completion, store Client ID in mysocket  
   Inst_TcpAccept(true,Inst_TcpListen.ListenID);
   if Inst_TcpAccept.Done then
      mysocket:=Inst_TcpAccept.ID;
      mycounter := mycounter + 1;
      Inst_TcpAccept(false,Inst_TcpListen.ListenID);
   end_if;
 
5: // Start function block to receive characters over the socket connection
   Inst_TcpReceive(true,mysocket,MAX_CHAR_TO_RECEIVE);
   mycounter := mycounter + 1;

6: // Wait for characters to be received, store in mystring
   Inst_TcpReceive(true,mysocket,MAX_CHAR_TO_RECEIVE);
   if Inst_TcpReceive.Done then
      mystring:=Inst_TcpReceive.Data;
      Inst_TcpReceive(false,mysocket,MAX_CHAR_TO_RECEIVE);
      mycounter := mycounter + 1;
   end_if;
7:
   mycounter := 5;

end_case;
TCP.xk5 (2.24 KB)

Comments

Submitted by Paul Norström on Fri, 05/21/2021 - 14:28

Hello,

I've set up my PDMM as a server according to your example here with a few modifications.
But I'm having trouble handling disconnects.

My client connects and sends a few bytes, PDMM receives them correctly and enters a msg handler subprogram which parses the message and responds accordingly.
After my client receives the response it closes the stream and the socket.


<From my c# client program>

After the client disconnect I notice this in the controller log: 16105
TcpBinReceive error: pSocket->Read operation returned errorID=16105 errno=248. | ControllerLib.cpp:2765 

So some internal error occured and the socket is most likely broken.
So I set the EN_CONNECTION variable to false and shortly after that to true again to reset the socket. 

But this time I get this error : 16100
TcpListen internal error: Bind returns error.                                  | ControllerLib.cpp:3103        

And I keep getting that error no matter how many times I reset.
So I am guessing even if I managed to write some better fault handling with error checks and a TcpIsValid block, I cant handle this error without restarting the device.

Any ideas? 

I can add some wireshark dumps if that helps.

 


         



 

Submitted by Stefano Giacomelli on Mon, 05/24/2021 - 15:49

Hi Paul.
Disconnecting the client and setting EN_CONNECTION variable to false the function Inst_TcpReceive remains stuck because its En=TRUE.
When the code arrives again there (mycounter=5) the function don't receive anything because is currnetly stuck.
Try to find a way to set its En=FALSE before setting EN_CONNECTION variable to false. 

 

About this Article

Stefano Giacomelli