Issue with simple Ethernet LAN Server

This code is a basic template for a larger code. Its a TCP server and listens on port 9999. When the TCP client sends a four letter query, it checks and responds suitably. Only two valid queries are there : FULL and LAST.

If by mistake the user sends any other four letter query it responds " Undefined Query!!"

But if the user my mistake sends a wrong query that is longer than four characters it gets stuck and keeps on responding with " Undefined Query!!" even for valid queries. Why ??

/*
 * 
 * Hardware : Arduino UNO board ; 
 * Ethernet shield attached to pins 10, 11, 12, 13.
 * 
 * Simple Ethernet server to respond to a TCP Client..
 * 
 * 
 */
//=================== INCLUDE ====================

 // Include Libraries :
 
 #include <Ethernet.h>
 #include <SPI.h>


//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//================== DEFINES ======================
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

// Define the Ethernet interface. 
 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Random MAC
 IPAddress ip(192, 168, 1, 10);  // Static IP
 EthernetServer server(9999);    // Server is listening on port 9999
 

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//================= SETUP ========================= 
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
 void setup() 
 {
// START SERIAL FOR DEBUGGING
  Serial.begin(9600);

// START THE ETHERNET INTERFACCE
  Ethernet.begin(mac, ip);
  server.begin();                   // Start the Server at specified IP and Port
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
 }


//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//================ SCAN LOOP ======================
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

void loop() 
{
// Endless loop execution starts here :

 String readString1;
 char ServerMsg[40]; 
 char count;
 unsigned char CaseNo ;


//#################### LAN SERVER SEGMENT #################

  EthernetClient client = server.available(); 
 if (client) {                                // Wait for the client to send a request  
    while (count < 4) {                       // Reads the character sent by the client into a String variable. 
      if (client.available()) {
        char c = client.read();
         count ++;     
         readString1 += c;
        } 
     }
       
        count = 0;
        CaseNo = 3;
        if ( readString1 == "LAST" ) CaseNo = 1;
        if ( readString1 == "FULL" ) CaseNo = 2;
        
        switch( CaseNo ) { 
        case  1 :  {         // Read and send the last Cycle Data to the TCP client..
          sprintf ( ServerMsg, "FULL CYC DATA" );    
          server.write( ServerMsg ); 
        }
      break;
      case  2 :  {            // Read and send all available Cycle Data to the TCP client..
          sprintf ( ServerMsg, " ALL CYC DATA ");    
          server.write( ServerMsg );  
          }
      break;
      default :   {
            sprintf ( ServerMsg, "Sorry. Udefined Query !! ");
            server.write( ServerMsg);
       }
    }
  }  

 
 delay(50);                            
  
 }// End of main loop. 

//================ SCAN LOOP END =================

If the user sends "HeyWhatCanIDo", that's more than 4 characters. Only the first 4 are read and processed. The rest remain in the queue, for the next read operation to deal with.

You MUST use an end of packet marker, and read an entire packet each time.

if (client)

if (client.available())

Though I have used the above code, its based on the example and I must admit I am not too sure as to what happens in each line . Let me pen as I understand:

if(client) … Is there is a string in the TCP incoming buffer to be read ?

if(client.available()) … is there still more characters to be read. And does this mean as each character is read, it is removed from the buffer ?

And does this mean as each character is read, it is removed from the buffer ?

Yes, just like Serial.read().

The below basic web server code will print what is received from the client browser, which is more than just the info being sent. You will need to observe what is being received and develop your way to check for the key words you are looking for. If you are using telnet or other communication type, you will need to adapt to that.

//zoomkat 12-08-12
//get submit box code
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html or use a '
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields
//note that the below bug fix may be required
// http://code.google.com/p/arduino/issues/detail?id=605 

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 102 }; // 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(5, 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("server text box test1"); // 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); //see what was captured

          //now output HTML data header

          client.println("HTTP/1.1 200 OK");
          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>HTML form GET example</H1>");

          client.println("<FORM ACTION='/' method=get >"); //uses IP/port of web page

          client.println("Pin 5 'on5' or 'off5': <INPUT TYPE=TEXT NAME='LED' VALUE='' SIZE='25' MAXLENGTH='50'>
");

          client.println("<INPUT TYPE=SUBMIT NAME='submit' VALUE='Change Pin 5!'>");

          client.println("</FORM>");

          client.println("
");

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

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

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

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

        }
      }
    }
  }
}

Instead of setting up a counter to read the characters, just reading all the available characters did the trick ! Works fine form 1 character to n characters. This the change done in code :

 EthernetClient client = server.available(); 
 if (client) {                                       // Wait for the TCP client to send a request                     
     while (client.available()) {                 // Read all characters sent by the client into a String variable. 
        char c = client.read();    
        readString1 += c;
     }