Hi,
the main goal is to avoid that the program gets stuck somewhere. This I have to avoid at all costs, because it means I have to climb up on my carport, pick up the arduino and fix it in my office.
The response is needed for debugging only, in production I do not need it.
But I still have to avoid infinte loops - no matter where they come from
This is what I call "Perfect World" code. If the server doesn't stall and the connection doesn't fail, it works. If either of those things happen after the connection is established, this while(client.connected()) loop becomes an endless loop.
while (client.connected())
{
if ( client.available() )
{
c = client.read();
Serial.print(c);
}
}
Serial.println();
client.stop();
Gawan:
Hi,
the main goal is to avoid that the program gets stuck somewhere. This I have to avoid at all costs, because it means I have to climb up on my carport, pick up the arduino and fix it in my office.
The response is needed for debugging only, in production I do not need it.
But I still have to avoid infinte loops - no matter where they come from
Well, the loop() function is an infinite loop.
But - if you have a time out for not receiving a server response, you have to handle the consequences of a missed response. For example, you can engineer a re-try. But too many failed re-tries might constitute an error. So if you are depending on server data, there is no way to avoid getting "stuck" unless you have a plan B. I think what you're getting at, is that the application should recover whenever the server recovers. So repeated infinite retries would be okay, even though it's a "loop". Is that correct?
Basic client test code that sends a request to a server for your current internet IP address, and then captures the response in a String that can be evaluated for desired data.
//zoomkat 11-04-13
//simple client test
//for use with IDE 1.0.1
//with DNS, DHCP, and Host
//open serial monitor and send an e to test client GET
//for use with W5100 based ethernet shields
//remove SD card if inserted
//data from myIP server captured in readString
#include <SPI.h>
#include <Ethernet.h>
String readString;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
char serverName[] = "checkip.dyndns.com"; // myIP server test web page server
EthernetClient client;
//////////////////////
void setup(){
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
while(true);
}
Serial.begin(9600);
Serial.println("client readString test 11/04/13"); // so I can keep track of what is loaded
Serial.println("Send an e in serial monitor to test"); // what to do to test
Serial.println();
}
void loop(){
// check for serial input
if (Serial.available() > 0) //if something in serial buffer
{
byte inChar; // sets inChar as a byte
inChar = Serial.read(); //gets byte from buffer
if(inChar == 'e') // checks to see byte is an e
{
sendGET(); // call sendGET function below when byte is an e
}
}
}
//////////////////////////
void sendGET() //client function to send/receive GET request data.
{
if (client.connect(serverName, 80)) { //starts client connection, checks for connection
Serial.println("connected");
client.println("GET / HTTP/1.1"); //download text
client.println("Host: checkip.dyndns.com");
client.println("Connection: close"); //close 1.1 persistent connection
client.println(); //end of get request
}
else {
Serial.println("connection failed"); //error message if no client connect
Serial.println();
}
while(client.connected() && !client.available()) delay(1); //waits for data
while (client.connected() || client.available()) { //connected or data available
char c = client.read(); //gets byte from ethernet buffer
readString += c; //places captured byte in readString
}
//Serial.println();
client.stop(); //stop client
Serial.println("client disconnected.");
Serial.println("Data from server captured in readString:");
Serial.println();
Serial.print(readString); //prints readString to serial monitor
Serial.println();
Serial.println();
Serial.println("End of readString");
Serial.println("==================");
Serial.println();
readString=""; //clear readString variable
}
Gawan:
But it reads the answer once and as the client never disconnects on his own, it gets stuck in the WHILE.
Is there any good way to solve this ?
An HTTP response contains a header named "Content-Length". If that header is not present, then the end of the response is signalled by the connection being dropped. If that header is present, then the response is exactly that many bytes after the final blank line that signals the end of the headers.
The HTTP specification is named rfc-2616 and is available here and many other places.
(EDIT) There are two exceptions. When the request is a 'HEAD' request, Content-Length will show what the length of the body would be if it was sent, but the body is not actually sent. When the request includes an If-Modified-Since header, and the data has not changed (ie: the client should use a cached copy), then a 304 (not modified) will be sent in reply with no body. Again, the content-length may be present and indicates the size of what the body would be if it were sent.
(EDIT 2) Try adding a "Connection: close" header to your request.
Incidentally, your code has another bug. You use println to send the data. This means that you are sending an additional line break beyond what you said the length of your message was. Either use print, or use data.length()+1 for the length of your message.