Having problems with my own skecth, I agregated 3 sketches from examples: NTP client, UDPSendReceive and Web Server, all are running simultaneously.
If the NTP server is "pool.ntp.org" the DNS.cpp is not working correctly but using 192.168.0.254 (my Internet box) runs very fine.
The bad behaviour of DNS.cpp is permanent after the first HTTP request but http request continue to run fine and UDP send-receive continue to run fine...
When this bad behaviour occurs, resetting the HTTP server made the DNS request to run again fine 1 time only....
It may help to know what exactly fails, what are the symptoms of a fail? Does it get stuck (your description is contrary) or does it get a wrong IP address? If that's the case, what IP do you get?
When the problem arrives, the DNS request stays stuck (in gethostbyname() ) with a result of -1 (timeout) and if you insist (retry mechanisms) the Arduino reboots.
After 1 bad answer (timeout) the DNS process continues with requests timeouts (-1 in gethostbyname() )
So i investigated the problem and found that resetting the HTTP server (i added a comand to the sketch) after having a DNS timeout (-1 in gethostbyname() ) resume the DNS process and the answer which follows got a valid IP address then after an HTTP request, the DNS process becomes stuck again... and so on....
More information:
The mechanism is as follow: the HTTP part receive and send messages while the UDP part is also receiving messages (no send) and every 13.125 seconds the Arduino sends an NTP request to pool.ntp.org.
Most of the time the NTP request abort because the DNS request stays stuck in getHostByName() with a timeout but while this happens, HTTP and UDP processes continue to work correctly only the DNS requests don't work.
Resetting the HTTP stack ( http_server.begin() ) resolve the DNS problem for one or maybe some requests.
Other information:
Retrying in getHostByName cause an arduino reboot
Using an IP address directly instead of a hostname never shows the problem.
The problem arrives only when UDP is already running
Hardware is Mega2560 + W5100 + DS3231
Software is IDE 1.8.8 Ethernet library is 2.0.0
When the problem arrives, the DNS request stays stuck (in gethostbyname() ) with a result of -1 (timeout) and if you insist (retry mechanisms) the Arduino reboots.
How do you know? There is no call to gethostbyname() in your sketch. I guess you mean getHostByName() it would be interesting how you called it to get that result.
If the Arduino reboots in your sketch you probably had a memory corruption. Your sketch wastes a lot of RAM by not using the F() macro for the constant strings. Maybe this is causing the problems. I can imagine that you modified some library files to get the above information which might waste even more memory.
So i investigated the problem and found that resetting the HTTP server (i added a comand to the sketch) after having a DNS timeout (-1 in gethostbyname() ) resume the DNS process and the answer which follows got a valid IP address then after an HTTP request, the DNS process becomes stuck again... and so on....
Post the complete code that lead you to this conclusion! In the posted code there is no sign that might enable you to even get the information what getHostByName() returns.
HTTP and UDP processes continue to work correctly only the DNS requests don't work.
The Arduino IDE (by default) doesn't have the concept of a process or any form of multitasking. What do you mean by above sentence?
Retrying in getHostByName cause an arduino reboot
Again, your sketch doesn't call getHostByName() so how do you know and how are you able to retry?
Hello
The problem is shown by addind a "Serial.println(ret)" in getByHostName() in DNS.cpp
The sketch is a very simple example to put the problem in evidence (mine is too big and exhibit the same problem as the example provided). So, it is very easy to download it, install it, modifiy the network settings paratmeters and run it to see the problem.
Arduino is not multitask but as the loop is written it can do these tasks one after the other.
I isolated getByHostName() and processResponse() and buildRequest() from DNS.cpp and use it in my own sketch successfully and without any problem. For this I don't open a new UDP socket but use the existing one in the sketch.
Moreover, in my investigations I added a retry mechanism in getByHostName() (in DNS.cpp) and seen that it was not a good idea : reboot.
I don't think that the problem is in DNS.cpp but in the socket mechanism, this is why i asked if someone was knowing a method to debug this kind of problem.
I isolated getByHostName() and processResponse() and buildRequest() from DNS.cpp and use it in my own sketch successfully and without any problem. For this I don't open a new UDP socket but use the existing one in the sketch.
Have you tried your sketch without any modification, on a new installation of the IDE?
Moreover, in my investigations I added a retry mechanism in getByHostName() (in DNS.cpp) and seen that it was not a good idea : reboot.
Sounds like your modification was wrong. As we haven't seen the complete code (all your modifications to the base library) we cannot find the error.
I don't think that the problem is in DNS.cpp but in the socket mechanism, this is why i asked if someone was knowing a method to debug this kind of problem.
Usually Serial.print() is a bad idea to debug such stuff. I debug using Arduino pins I set high if a certain point is reached, or I use a complete port and output a binary number there. Then I attach a logic analyzer and go from point to point. I don't know if that's the best way to do it but in most cases it works.
Yes, it is a fresh install because i was in 1.8.7 at the beginning, i tray to stay up to date for IDE and libraries.
My sketch is too big, so i decided to use examples provided in the 1.8.8 IDE to agregate 3 of them without changing important part of code, just somelines without importance. This avoid any personal code which could be the cause of the problem.
Secondly, i have had a look to the library, particularly DNS.cpp, the retry mechanism has been implemented to the getHostByName() procedure but has been commented out, it is not my work, i just suppressed the commentary characters ( // ) to validate the mechanism and this conducted the sketch to reboot the Arduino when requesting DNS names.. just a constatation.
I know the serial.print is not a good idea but it confirmed the "timeout", in fact this is not a real timeout but a socket attribution problem or similar because the DNS.cpp is working correctly when set appart from the socket mechanism (socket.cpp). As in my case I use the already running UDP process instead of opening a new UDP process (iUDP in DNS.cpp not used)
Thanks for your help, i will stay with my isolated DNS process which is running very fine. Moreover, my knoweldge level is too low to investigate deeper.
Secondly, i have had a look to the library, particularly DNS.cpp, the retry mechanism has been implemented to the getHostByName() procedure but has been commented out, it is not my work, i just suppressed the commentary characters ( // ) to validate the mechanism and this conducted the sketch to reboot the Arduino when requesting DNS names.. just a constatation.
I see only two possibilities of that code to fail: Invalid hostname string (no null byte termination) or insufficiant memory (RAM).
As you told us that the sketch from the initial post reboots also if only the retry loop is activated (no Serial.print()), it has to be the latter. Looking through the code I haven't found yet a memory leak. Given the hostnames you provided, it seems to be a problem if the DNS server returns CNAME records.
Just to be sure we have the same code: I'm using version 2.0.0 of the Ethernet library.
As in my case I use the already running UDP process instead of opening a new UDP process (iUDP in DNS.cpp not used)
I cannot see a way to use getHostByName() without using iUDP. Maybe it's time to post your version of Dns.cpp.
I'm using Ethernet library version 2.0.0 and IDE 1.8.8
Using the code in my first post is the best way to avoid eventual memory problems of my own code.
Moreover, I added a lot of verifications and return codes (in DNS.cpp) in ProcessResponse() to see eventual wrong answer from the DNS and eventual ProcessResponse() returning datas causingthe problem. But ProcessResponse() never failed and getHostByName() always returned -1 (TIMEOUT) when the problem arrives (as the process was correct, i removed these debugging lines).
This is why I added a command "http_server.begin()" to my sketch and seen that name resolution worked again until it fail again.
I don't have a version of DNS.cpp, i just extracted my code from DNS.cpp and inserted it into my own sketch. The code from DNS.cpp is running very fine, i think it is not responsible of the problem.
I cannot tell you more because of my poor knoweledge, sorry.
I don't have a version of DNS.cpp, i just extracted my code from DNS.cpp and inserted it into my own sketch.
In the posted code there is no code from DNS.cpp. Do you say that this code is not working with a unmodified Ethernet library from IDE 1.8.8?
I have the impression that you try to tell us that your modifications were not responsible for the failures but you never tried with an unmodified version.
this code(agegated 3 examples) + unmodified Ethernet library 2.0.0 and ide 1.8.8 shows the problem.
Does that mean if I compile the code from post #1 on my IDE I get one request finished and all other requests must fail? Or did you mean some other code you didn't post?