Host Engineering Forum
General Category => Do-more CPUs and Do-more Designer Software => Topic started by: Andrew S on July 01, 2019, 12:23:37 PM
-
I'm having a heck of a time getting my BRX to talk to an in-house webserver using HTTPCMD. Even though the webserver appears to be functioning correctly from multiple pc-based clients (so there's no firewall issue here) the PLC won't connect to it. I'm connecting using an IP address and I've double-checked the port number. The dialog is simple - I send a GET with a specific URL to the server, and the server responds with a 5-digit code. There's no HTML involved and I"m not sending any special headers. I'm confident that the network config isn't the issue here.
DMLogger reports:
Connecting to HTTP server...
Error connecting to HTTP server
Couldn't open TCP connection with specified device in HTTPCMD
Response Status code is 0.
Any thoughts about how I could debug this further? I'm pulling my hair out (at least what little hair I have left....)
Thanks, Andrew.
-
Using Wireshark to look at the messaging back and forth to the server might give some clue. It would need to be installed on the server or a switch that supports mirroring would need to be used to see the traffic.
-
Thanks. I did look at Wireshark but it shows only the TCP SYN received at the server. Nothing else appears to happen, not even an ACK. It's very strange.
-
I noticed that the Ethernet header has the destination set to the broadcast address (FF:FF:FF:FF:FF:FF). Am I missing something in the HTTPCMD that's causing this?
EDIT: Sorry, edited to say Ethernet header, not TCP header. Also, the IP dest IS set correctly.
-
What type of server is it (IIS, Wamp, ???)?
When you send a test call to the server, are you testing using the IP and port, or using a name?
-
What type of server is it (IIS, Wamp, ???)?
When you send a test call to the server, are you testing using the IP and port, or using a name?
This is a NodeJS Express server. I'm using the IP and port. The server is on the same subnet as the PLC. The packet doesn't make it as far as the webserver - I think the issue with the destination being the broadcast address is the root cause of the problem. I'm just not sure how I can resolve it.
In case it matters I'm using DMD 2.6.1.
-
Are you using an existing TCP connection?
-
Are you using an existing TCP connection?
No. I'm using the HTTPCMD statement to dynamically open and close the connection.
-
Just for kicks, you may want to try opening a connection externally, and then see if the command will run.
BTW:
I have not used the new HTTPCMD instruction, but have extensive experience in raw TCP using DMD.
-
I'll give that a try. Thanks.
I looked in the System Information screen and noted a couple of messages that appear to be relevant:
In Warning Messages:
"Device driver error - $DriverError (ST143)"
In Last Error(s):
Unknown error (64)...in HTTPCMD at" ...
-
The OPENTCP command fails but doesn't provide any diagnostics about why.
-
Interesting.
If I had time, I would run some tests on my own, but I'm kinda covered up...
You might post some screenshots of what you have so we can take a quick look.
-
I'll do that. Thanks for your assistance.
-
We refactored the errors returned from OPENTCP and any of the instructions that use a TCP connection (HTTPCMD, EMAIL), with the specific intention of distinguishing between connections that were dropped by the server vs those that never succeeded. Previously both of those used a generic "something broke" error. The 64 code means that the connection was never established to begin with, and somebody (read: Yours Truly) forgot to add an error description to the appropriate table. So basically the controller isn't getting the answer from the server.
FF:FF:FF:FF:FF:FF is the broadcast address, which means that a valid TCP address either wasn't provided, the ARP didn't work, or the DNS came back with something jacked up.
-
Are you using a variable for the IP?
If so, try viewing it as an IP from a Dataview to make sure the format is correct.
-
I'm using a directly assigned IP address. It's not a variable.
I came to the same conclusion Bob, but of the scenarios you mentioned I don't know that any really fit my situation. I've validated and re-validated the IP address (I'm able to use the exact same IP address from another client on the same subnet), it's on the same subnet as the server (so unlikely to be an ARP failure) and we're not using DNS for this since it's an IP address.
Perhaps I just need a holiday...
-
I'm still beating my head against a wall with this.
I added a PING statement which works fine. This tells me that the network connectivity is good.
Wireshark shows TCP SYN packets being sent from the PLC to the Server, but no ACK responses come from the server. However, all other clients I've tried elicit a correct response from the server.
Here's the really strange thing - if I run the PING first, the HTTPCMD succeeds, and continues to succeed for a while. After a period of inactivity it starts failing again, until I PING the server once more.
Is it possible that ARP handling is failing for HTTPCMD but it's working for PING?
Another thing to note is that it works just fine (always) on a different NodeJS server. The server that's failing is an Ubuntu 19.04 box running in a Hyper-V VM on my Win10 box. Once again though, other clients always connect to it just fine - it's just the PLC/this-particular-server combo that's causing a problem.
-
Is it possible that ARP handling is failing for HTTPCMD but it's working for PING?
Doubtful. Stack doesn't know the difference.
-
Another thing to note is that it works just fine (always) on a different NodeJS server.
By "it", do you mean the BRX PLC doing HTTPCMD?
-
I have only piddled with NodeJS, but have done a lot with IIS.
In IIS you can set up your server to only respond to a request based on the Name versus an IP request. I do not know if this "filtering" happens at the connect, or at the request level.
The only servers that I maintain are on private networks, so we always set them to work based on the IP.
Maybe the NodeJS server doesn't like the request from the BRX?
-
By "it", do you mean the BRX PLC doing HTTPCMD?
Yes. The solution works end-to-end if I run a PING first. At least for a while.
Another weirdness I've come across is that I can't get HTTPCMD to succeed (ever) if I use TCPOPEN. The TCPOPEN connects successfully (and the CLOSE works correctly too) but the HTTPCMD always fails without an error code (just the error bit being set). Since there's no diagnostics I can't tell why it fails but if I bypass the TCPOPEN and CLOSE statements and change the same HTTPCMD statement to specifically use either an IP address or hostname, it succeeds.
-
Maybe the NodeJS server doesn't like the request from the BRX?
It's not getting as far as the server (which doesn't by default care how you reach it - IP address or any hostname is ok by default). The problem occurs lower down at the TCP negotiation.
-
By "it", do you mean the BRX PLC doing HTTPCMD?
Yes. The solution works end-to-end if I run a PING first. At least for a while.
Another weirdness I've come across is that I can't get HTTPCMD to succeed (ever) if I use TCPOPEN. The TCPOPEN connects successfully (and the CLOSE works correctly too) but the HTTPCMD always fails without an error code (just the error bit being set). Since there's no diagnostics I can't tell why it fails but if I bypass the TCPOPEN and CLOSE statements and change the same HTTPCMD statement to specifically use either an IP address or hostname, it succeeds.
The option to TCPOPEN then HTTPCMD may not work. We had good thoughts, but reality got in the way. I thought that option got removed, but I guess not.
-
What if you load the program on a SIM on one of the PC's that can access the server?
-
What if you load the program on a SIM on one of the PC's that can access the server?
Same behavior as the PLC.
-
Same behavior as the PLC.
Windows stack is *very* different than the hardware's stack. I'd be looking elsewhere.