Client.connect halts

good day everyone,
on my Arduino nano I have the following sketch function to connect to a server with a POST query string in 2 attempts:

byte conn_attempts = 2;
bool connected = false;
while (!connected && conn_attempts-- > 0)
  {
    if (client.connect(serverName, 80))
    {
      connected = true;
      client.println(F("POST /query.php HTTP/1.1"));
      client.print(F("Host: "));
      client.println(serverName);
      client.println(F("Content-Type: application/x-www-form-urlencoded"));
      client.print(F("Content-Length: ")); 
      client.println(query.length());      
      client.println();                    
      client.println(query);  
    }
  }

Now, if the Ethernet shield (a standard W5500 module) is physically not connected to anything (cable disconnected), the sketch runs properly and after the two attempts, runs through.
The same happens when it is connected with the internet, sending correctly the query string.

The problems start when the cable is connected to a router, which however does not provide internet access. In that case, the routine freezes at the line containing client.connect. I realized that, because I have a watchdog feature enabled at 8s, so it looks like the client.connect() function is stuck for longer than 8 seconds. From the Arduino manual though it is documented that the default timeout is 1000ms, why is the connect still trying to connect for longer??
Also overriding the timeout again manually at setup() through the line
client.setTimeout(1000);
does not solve the issue.

Any ideas appreciated

That's the default timeout for the connect() variant that gets an IPAddress parameter. You seem to provide a server name (you failed to provide complete code, so that's just an educated guess) and that name has to be translated into an IP address first. The timeout for that function is 5s and in the current implementation you cannot set that timeout if you use that version of the connect method.
Now you can say that 5s shouldn't trigger the watchdog. You also failed to tell us which version of the IDE you're using. Older versions did try the DNS lookup 3 times before giving up, using the 5s timeout each time, resulting in 15s before returning an error.

thanks for the answer, which is possibly guiding me in the right direction.
Regarding the missing info:
I am using the Arduino IDE latest version, 1.8.16 running on Win10 and all boards defs are updated.
The servername is initialized as global string of an existing website in the form
char serverName[] = "www.website.com";
and as I said, it works fine when connected to the internet.

I have played around with the code a little and verified your info: you are quite correct, disabling the WATCHDOG indeed the connect freezes now for exactly 30seconds, which is twice 15s, because my routine is making 2 attempts before giving up. I could not find anywhere the mention at the 5s timeout with 3 attempts for the connect method.

Yet I'd like to completely understand how client.connect is working:

  1. if the routine is waiting IP, why is this not the case when the cable is disconnected? Is there any difference the router is causing to process in the code, which is not done when the cable is totally absent?

  2. Do I understand correctly from your wording, that there is another way to connect to a server to do a POST query (or what do you mean by "...if you use that version of the connect method"?), if yes, I would appreciate directions

In the current version of the IDE (1.8.16) there's only one attempt, so the call should return after 5s.

Again: post complete code, you're wasting our time if you hide important information!

The name-to-IP resolution is done using the internet. If you don't have an internet connection it times out, if you have a connection it will provide a result within a few dozens of milliseconds (in a normal environment).

There is a version of the connect method which doesn't accept a server name but an IPAddress object. If you use that method the timeout of 1 second (default) will be kept. The example in the reference page does make use of that version of the method.

no worries, my complete sketch is over 2k lines, so definitely it'll waste your precious time more than necessary just to familiarize with it, that's why I did not post the complete code.
Anyways, I have isolated the part causing the issue and will try to skim it the most I can, so to focus only on the point in object here.

Still ideally I would replicate the behaviour without the extra long timeout as in the case where the cable is completely disconnected even when the target URL is not reachable (but board cabled to the router), would that be possible? Possibly just a lack of understanding how network functions are implemented in the libraries, there must be extra actions done once the IP is assigned from the router which clearly does not trigger the delay when instead the cable is not connected.
Also, due the nature of dynamic IP of target url and shared domain on same server, it won't be possible to connect just through its IP (not static and not unique anyway)

What does "target URL is not reachable" mean? Is only the HTTP server down or does the hostname not exist? For the timeout calculation these two situations are completely different.

I get the impression you're lacking an understanding of the network functionality at all.

I assumed that Arduino was never assigned an IP by the router, because without a cable the router isn't able to assign an IP at all and the code should stop much earlier. As I mentioned several times before: without complete code we're just guessing and wasting our time.

Another important information you failed to tell us before. A server using a dynamic DNS entry may need much longer for DNS lookup because the address cannot be cached by any server on the way.

You should definitely start by posting complete code (even if that's a lot of code, we're able to look through more than a few lines and search for the information we want) and a description of what you're trying to achieve.

It seems you want to recognize a failed environment (no cable, failed network setup, etc.). You shouldn't try to catch that using just timeouts but actively check the connection. For example, one way may be to ping the Google DNS server (8.8.8.8) to check if you have internet connectivity. You don't have to try to reach the DynDNS based server if you don't have any connectivity.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.