Arduino ethernet server connection problem after some requests

Hi,

I am building an arduino based solution for our window blinds to be controlled via a web page. The arduino acts as a web server and reads the requests from clients (in this case an iPhone accessing the web page and sending commands).

I am having trouble getting the ethernet connectivity stable. It all works fine but the server becomes unresponsive after a couple of connection attempts. It is pretty consistent that after 4-5 connections the server does not answer any more.

I suspect that there is a problem with sockets not being closed but I have very little experience in this.

Attaching the core code I am using.

Any ideas from the community would be very appreciated to make this project successful.

Thanks!!!

#include <SPI.h>
#include <Ethernet.h>

String readString = String(1000);

EthernetServer server(2560);

byte mac[] = { 0x54, 0x55, 0x58, 0x10, 0x00, 0x24 };  // MAC address 84.85.88.16.0.36
byte ip[]  = { 192, 168, 188, 50 };                   // IP-address, please change to fit your network
byte gateway[] = { 192, 168, 188, 1 };                // Gateway
byte subnet[]  = { 255, 255, 255, 0 };

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
}

void loop(void)
{
  checkEthernet();
  delay(50);
}

void checkEthernet()
{
  EthernetClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (readString.length() < 1000) {
          readString = readString + c;
        }
        if (c == '\n')
        {
          currentLineIsBlank = true;
        } else if (c != '\r') {
          currentLineIsBlank = false;
        }

        if (c == '\n' && currentLineIsBlank) {

          // ANALYZE RESPONSE AN TAKE ACTION

          Serial.println(readString);
          client.println("OK");
          readString = "";
          break;
        }
      }
    }
    // give the web browser time to receive the data
    delay(5);
    // close the connection:
    client.flush();
    client.stop();
  }
}
String readString = String(1000);

First, I doubt that this is doing what you think it is doing. Print readString in setup() to see what it is ACTUALLY doing.

Second, even if it WAS creating a String instance reserving space for 1000 characters, that is more than half the available memory on the Arduino. You REALLY need to get real as to how long a client request is.

void loop(void)
{
  checkEthernet();
  delay(50);
}

The delay() is completely useless. Having loop() do nothing but call one function() is pointless. Just do the work in loop().

        if (c == '\n')
        {
          currentLineIsBlank = true;
        } else if (c != '\r') {
          currentLineIsBlank = false;
        }

        if (c == '\n' && currentLineIsBlank) {

By the time the last line is executed, it there a snowball's chance in hell that currentLineIsBlank is not true?

          // ANALYZE RESPONSE AN TAKE ACTION

          Serial.println(readString);
          client.println("OK");
          readString = "";
          break;

I fail to see that any analysis was done or that any (useful) action was taken.

SurferTim has some code, posted on the playground, and in other places that you can search for that analyzes the state of the connections on the Ethernet shield. You should find that code, and add it to loop() (since its doing nothing anyway), and see if you are failing to close the connection properly when a client opens a connection. The Ethernet shield can only handle 4 simultaneous connections. If you fail to close one properly, that reduces the number of connections that can be made.

Do that 4 times, and no more connections can be made. Sounds like your situation...

If your server code is exposed to the internet, you can get client connections that never send a newline or a blank line, especially if the server is listening on a non-standard port. That will cause your code to lock up.

Here is a link to my server code on the playground.
http://playground.arduino.cc/Code/WebServerST

What is being sent to the arduino that requires 1000 bytes of capture space? The client.flush(); might be causing issues. Below is some simple server test code that controls a pin on the arduino. You might try it to see if you can control the pin more than 5 times.

//zoomkat 10-6-13
//simple button GET with iframe code
//open serial monitor to see what the arduino receives
//use the ' instead of " in html ilnes 
//address will look like http://192.168.1.102:84/ when submited
//for use with W5100 based ethernet shields

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //ethernet shield mac address
byte ip[] = { 192, 168, 1, 102 }; // arduino IP in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port

String readString; 

//////////////////////

void setup(){

  pinMode(4, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
  Serial.println("servertest1"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

          //now output HTML data header
             if(readString.indexOf('?') >=0) { //don't send new page
               client.println("HTTP/1.1 204 Zoomkat\r\n\r\n");
             }
             else {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Zoomkat's simple Arduino button</H1>");
          
          client.println("<a href='/?on1' target='inlineframe'>ON</a>"); 
          client.println("<a href='/?off' target='inlineframe'>OFF</a>"); 

          client.println("<IFRAME name=inlineframe style='display:none'>");          
          client.println("</IFRAME>");

          client.println("</BODY>");
          client.println("</HTML>");
             }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf("on1") >0)//checks for on
          {
            digitalWrite(4, HIGH);    // set pin 4 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(4, LOW);    // set pin 4 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

Thanks so much for all your valuable replies!!! I will test today with your suggested improvements and will report back.
I had taken out the code to analyze the server response to make the code readable.