HTTP GET Request Odd Behaviour

Hi, I have an application with a web server that will respond with a very simple plain text "ok" or "error" string when it gets a HTTP GET request (it has more advanced JSON type responses for different requests, I am not really interested in these at the minute).

This is the code I am using with an Uno and Ethernet shield, fairly basic stuff really, every five seconds it is performing the GET request, reading what reply it is getting and then doing it again. It is mostly pieced together stuff from the web because I am more of a VB sort of person but I understand what it is doing.

#include <Ethernet.h>
#include <SPI.h>
 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetClient client;

String http_response  = "";
String dataInput = "";

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac); 
  Serial.print("IP address: ");
  Serial.println(Ethernet.localIP());
}

void loop() {
    http_response = "";
    char c[] = "";

    dataInput = "/JSON?request=controldevicebyvalue&ref=3&value=0";
    Serial.println(dataInput);
  
    client.connect("192.168.1.3", 80);
    client.println("GET "+dataInput+" HTTP/1.1");
    client.println("Host: 192.168.1.3");
    client.println("User-Agent: Mozilla/5.0");
    client.println("Connection: close");
    client.println();
    delay(500);
    
     for (int i = 0; i < 20; i++) {
        char c = client.read();
        http_response += c;
     }
     
     Serial.print("Response : ");
     Serial.println(http_response);
     Serial.println(); 
 
     client.stop();
     delay(5000);
}

The problem I have is the actual success rate, if I look at the debug window I will perhaps see a random (perhaps 1 in 5, perhaps 1 in 20) replies of code 200 suggesting that it has been successful (and the corresponding action in the server). So with this I think the structure of the data is fine. I have tried extending the delay and that does nothing.

I am really confused, my understanding that HTTP headers are not actually mandatory except for the Host header in HTTP 1.1, using the POSTman Chrome extension I can confirm that I can send these same requests as often as I want with no additional headers (no Content-Type, Auth etc) so I know they actually work just seems not to be from the Arduino.

I am completely lost as to why this is working very occasionally, can anyone help me?

Thanks...

You need to read the entire response from the server, regardless of whether or not it is more or less than 20 characters.

Assuming that there will be 20 characters to read after the half second delay is a piss-poor way of writing code.

You might want to check whether client.connect succeeded too.

PaulS:
You need to read the entire response from the server, regardless of whether or not it is more or less than 20 characters.

Assuming that there will be 20 characters to read after the half second delay is a piss-poor way of writing code.

Thanks for the replies, quite probably a poor way most of it was hacked together as I say, I am much happier in .net and perhaps I should of bought the NETduino I talked myself out of the other day. My thought process was that I was not interested in the reply and I could tell whether or not it went on the basis of the first 20 characters. I know what the reply headers are from sending the GET from Chrome and they are the same that I get when I get a successful send from the Arduino. If they are important these are the replies from Chrome (which as I say are the same when I get a success from the Arduino);

Accept-Ranges ?none
Cache-Control ?no-cache
Content-Length ?2
Content-Type ?application/json; charset=utf-8
Server ?HomeSeer

Are you saying I need to read the whole response regardless of whether or not I am interested in it actually doing anything in the Arduino? I know there is client.available and I could sit in a loop until I emptied read all of the data from it but is there any other way that I am missing or could you suggest the preferred way of doing it.

As per wildbill's post I do now test whether it is connected or not, it does appear to connect every time.

void loop() {
    http_response = "";
    char c[] = "";

    dataInput = "/JSON?request=controldevicebyvalue&ref=3&value=0";
    Serial.println(dataInput);
  
    client.connect("192.168.1.3", 80);
    
    if (client.connected()) {
    Serial.println("Connected");
    client.println("GET "+dataInput+" HTTP/1.1");
    client.println("Host: 192.168.1.3");
    client.println("User-Agent: Mozilla/5.0");
    client.println("Connection: close");
    client.println();
    delay(500);
    
     for (int i = 0; i < 1000; i++) {
        char c = client.read();
        http_response += c;
     }
     
     Serial.print("Response : ");
     Serial.println(http_response);
     Serial.println(); 
 
     client.stop();
     } else {
     Serial.println("Not Connected");
     }
     delay(5000);
}

Are you saying I need to read the whole response regardless of whether or not I am interested in it actually doing anything in the Arduino?

Yes. The socket that is used is not freed until all the data sent to the socket, by the server, has been read. Given that there are only 4 sockets, failure to read all the data, and enable the socket to be reused could result in your Arduino no longer being able to do anything.

I know there is client.available and I could sit in a loop until I emptied read all of the data from it

Not could. Should.

but is there any other way that I am missing or could you suggest the preferred way of doing it.

No, and you did.