KAS to receive data via TCP/IP connections
This article provides a simple example of receiving data via TCP.
- Import the attached program.
- 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;
Comments
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.
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.