Host Engineering Forum
General Category => Do-more CPUs and Do-more Designer Software => Topic started by: belias on December 26, 2019, 09:07:47 AM
-
Hello,
A little background: I use BRX PLCs for a lot of IOT functions (MQTT, automation integration, weather alerts, etc.) - it's great, and the fact that functionality keeps getting added is a huge bonus (MQTT, HTTPCMD, etc.). So first off, thank you!
I'm having an issue with a current project, where a server periodically sends an XML file via TCP, and I need to simply search the XML file for a portion of a string (no complex parsing). I have this same setup working with other devices that send TCP strings and there's no problem. In this case though, I always get an ST143 error (and the STREAMIN sets the error bit) each time the server sends the XML file.
Here's the interesting part: when I use a simple utility (like Packet Sender) in TCP server mode, it receives the XML file with no problem. I can then copy the contents, switch Packet Sender to TCP client mode and send the contents to the PLC and it works perfectly.
So...I decided to run a WireShark on the output of the device that's sending the XML file. It looks like it's sending a blank TCP packet after the packet containing the XML data (admittedly, I'm not an expert with TCP packets). See the attached pic (2.150 is the receiving computer, and 52.234 is the device sending the XML).
I've tried setting STREAMIN to only capture the first 10 bytes (hoping to ignore anything at the end that may be causing the problem), and still no luck. I'm attaching a pic of my current program...I typically don't use the method with the timer, but figured it was worth a try (from a different forum post).
Any help would be greatly appreciated. Thanks!
-
You mentioned that you got it working with a PC application "in server mode", meaning that the computer sending/initiating the data is the TCP "client". Hence, the Do-more PLC must be a TCP Server listening on a specific TCP port.
To function as a TCP Server, you must have a TCP Server device. Is your PVCam a TCP Server or TCP Client device? So, first make sure that you have a TCP Server device. You also need a TCPLISTEN instruction in $Main that will passively start listening on the needed TCP port. If you create the TCPLISTEN instruction first, you can easily create the TCP Server device from within the TCPLISTEN editor (or you can do it from the System Configuration dialog's Device entry sub-dialog). You need to know the TCP port that the other device is using, and provide that in the TCP Server device configuration dialog.
The TCPLISTEN instruction can kick off a program to process any TCP packet that is received. This other program code block is where you utilize Stage and with STREAMIN instruction(s).
If you have Microsoft Power-Point, here is a slide show on using TCP with Do-more:
https://hosteng.com/FAQFiles/TechSlides/Do-more%20Training%20%28Communication%20-%20Custom%20TCP%29.pptx
-
Hello,
My apologies for not giving enough info on the first post.
I do have the PLC configured as a TCP Server (so @PVCamTCP is a TCP Server), and I do have the TCPLISTEN in $Main that runs the stage program with STREAMIN. Port used is 7092.
I believe this is configured properly, because when I send the TCP packet from a PC to the PLC, the program works fine (and the XML is transferred to the string).
When sending from the actual device, $PVcamTCP.InQueue shows the value going to around 450 bytes, then it correctly moves to the timer which expires, the it goes Stage 3 where STREAMIN activates, however this results in the error bit being set and no data is transferred to the string.
-
I'd need to study this more from a PC (where I can better understand that trace) but it looks like the device may be connecting a second time, which is forcing the in queue to flush. Why are you waiting before processing the data?
-
I only tried the wait as a troubleshooting step. The XML doesn't have any stop delimeter, so I thought that might be an issue.
That doesn't appear to be the problem though, since when I send the packet from my PC it also doesn't have a delimeter and it works just fine (I know the data I need is in the first 200 bytes of an approx. 450 byte file, so I just set the length parameter).
See attached screenshot for program without the wait...also attaching the WireShark PCAP file.
Thanks again for the help and quick response.
-
It's doing what I suspected. The device opens a connection, sends 285 bytes, and immediately (1us later) closes the connection. About 80ms after completing the close, the device opens again and immediately closes without sending any data. I think BRX is clearing the queue when the socket gets re-opened, but you should easily be able to read the data within the 80ms before the second open. My guess is that you are overwriting your string on the second open (when you have no timer), and when you do have a timer, the re-open is forcing BRX to clear the queue. Both results look the same, but two different things are happening.
-
OK that makes sense for the scenario with the timer.
I'm not sure I follow where the problem is when there is no timer though.
I tried using a simple 2 line program (no stages) triggered off of the InQueue size > 0 and no luck. I also tried triggering the program off of the .Connected bit trailing edge and no luck there either.
-
OK that makes sense for the scenario with the timer.
I'm not sure I follow where the problem is when there is no timer though.
I tried using a simple 2 line program (no stages) triggered off of the InQueue size > 0 and no luck. I also tried triggering the program off of the .Connected bit trailing edge and no luck there either.
I think the program is getting run twice. The first time fills the string correctly and the second errors out.
Put a rising edge S3 contact in stage 3 and drive an INC instruction. I bet you will see it increment twice for each attempt.
-
Hmm...nope I only see it incrementing once for each attempt.
-
Hmm...nope I only see it incrementing once for each attempt.
Your counter shows 2...I guess that was after two attempts?
I'm not sure how to help you. Your device is clearly opening the connection a second time and immediately closing without sending anything. Without working on it myself all I can do is speculate that is causing a second run which is breaking things.
-
Yes...sorry. I grabbed the screenshot to show the placement of the INC and didn't look at the value. I had run through a few tests.
That's OK, I figured it was worth asking. Thanks for taking a look at it though - much appreciated.
-
I was able to eliminate the second blank packet transmission from the sending device (an Axis IP camera), and the problem still remains. As soon as the Axis sends the TCP string, the PLC will throw ST143 and the @TCPport will remain unusable until I run DEVCLEAR.
So in troubleshooting this some more, I posted 2 WireShark PCAPs at Stack Overflow showing (1) the exchange between PacketSender and the PLC which works properly, and (2) the exchange between the Axis IP camera and the PLC which does not. Both TCP strings are identical - but the packets transmitted are not.
I asked for a quick explanation of the differences, and I got back a useful answer.
Here's the quick version and a link to the original post:
The difference between these two pcap's is that PacketSender first does the TCP handshake and only then sends the data while the Axis sends the data already within the last packet of the handshake:
PacketSender Axis
> SYN > SYN
< SYN+ACK < SYN+ACK
> ACK > ACK + "PV_MOTION_ON"
> "PV_MOTION_ON"
It is perfectly valid TCP how the Axis behaves. It is kind of unusual though since typical socket programming techniques don't make it easy to send packets like the Axis does. The problem is still a wrong assumption inside the "TCP parsing utility" about how TCP works.
https://stackoverflow.com/questions/59553853/what-is-the-difference-between-these-2-tcp-packet-captures-one-doesnt-work