Problem:It's 2012 2013 and I still see my shield (programmed as client) functioning well but then freezing after some time while reading a txt file from a web server (GET method).It seems that it is related to the 4 sockets limit and the client.stop() function not working, so that sockets are not closed poperly.

I tried to follow all the several methods described in the forum, but they did not seem to work:- disable SD pin 4 (HIGH)- delays everywhere- flushing everywhere- checking client.connected();- checking client.status();- relaunching Ethernet.begin(mac) ..

These are old 2009-2011 advices, some of them are outdated or already included in the Libraries (SurferTim patch, ...).

So my question(s): What is the state or the art? Is the shield working for you?Is the client.stop() - socket disconnession solved or still an issue?

kev8

Just a quick update:Many thanks for your examples. I'm using them to debug more and trying new things.My general impression for now is that the shields functions, but freezes often when reading data (a text file) from the server (client.read()).I'll post more later.. bye!

Just a quick update:Many thanks for your examples. I'm using them to debug more and trying new things.My general impression for now is that the shields functions, but freezes often when reading data (a text file) from the server (client.read()).I'll post more later.. bye!

Are you sure the webserver is always available when Arduino tries to read that file? Somebody here on the forum wrote that the method "connect" of the "EthernetClient" class contains a loop of 10 seconds to retry connecting. If the webserver doesn't respond, Arduino hangs. That guy solved the issue by making Arduino act like a server. It waits for a command from the webserver and only then it connects to the webserver (this way Arduino knows the webserver is online).

No, the Arduino waits for the server to respond. It tries 5 times to establish the connection, then returns false if no connection could be established. You can shorten that time by editing the ethernet library files and setting the retry value to less than 5. This is part of the fault tolerance built into the internet.

You can't force it to make a connection that cannot be established. You can only wait a shorter period to determine it failed.

kev8

This is the code, sorry it's not very elegant and can be shortened a lot.

Basically, I took the code from http://arduino.cc/en/Tutorial/WebClientRepeating.Then I perform 2 GET:1. the first send sensors reading2. the second reads a TXT file containing 2 values for switching on/off 2 leds. I took the method here http://bildr.org/?s=clientand improved the readPage() function with SurferTim code.TXT file is a string like <01> (= 4 chars). Each number represents the LED status (0 or 1).The < and > are used to locate and extract the values, because the answer from server is about 120 chars (contains also headers).

// variables used by millis unsigned long lastConnectionTime = 0; // last time you connected to the server, in millisecondsboolean lastConnected = false; // state of the connection last time through the main loopconst unsigned long postingInterval = 10*1000; // time to wait before repeating connections

Serial.println("GET #1 - disconnecting."); } else { // if you didn't get a connection to the server: Serial.println("GET #1 - connection failed");}// ------------------------- End of GET #1//// // -------------------------- GET #2 --------------------------------------------------// -------------------------- (reads the values to be assigned to the LEDs ------------ // ------------------------------------------------------------------------------------

// note the time that the connection was made: lastConnectionTime = millis(); delay(1000);// // store the state of the connection for next time through// the loop: lastConnected = client.connected();

} // Close HTTP REQUEST} // Close void LOOP

// ----------------- FUNCTIONS -----------------------------

String readPage(){// This function// 1. read a TXT file in the form "<xy>" and // 2. extract xy and return them (xy can be "00", "01", "10" or "11") // 3. or return an error code (example "88") in case reads NULL values

// if more than 10000 milliseconds since the last packet if(connectLoop > 10000) { // then close the connection from this end. Serial.println(); Serial.println("Timeout"); client.stop(); } // this is a delay for the connectLoop timing delay(1); }

// extract and return valid LED values ("00", "01", "10" or "11") or "Error" if (inString.length() != 0){ // if inString is not null int a = inString.indexOf('<');// find the position of "<" int b = inString.indexOf('>');// find the position of ">" String extracted = inString.substring(a+1,b); // extract the text between "<" and ">" delay(1000);

From my testing, if any characters sent from the server end up in the rx buffer before the connection gets the client.stop(), the connection will not close properly and the socket is no longer available. Three more like that and there will be no sockets available.

kev8

Uh, his is a good point.. and a stupid error due to first time programming for HTTP communication!I was sure that since I was pushing some variables, the server did not have to answer.. instead the GET method requires an answer in any case.So, adding the reading of the answer is better.. fewer or no errors.

Sometimes (some hours) it still stops working, but I think it is related to some out-of-memory issue (my real code is about 20K.. there are a lot of debugging checks and Serial.prints). I'll try to reduce it and to increase the delay between two server requests and see if the code remains stable for some days..

Thank you Surfer and other people, it was an honor to have prompt answers from all of you!(.. and Happy New Year)