Go Down

Topic: Anybody have ~simple combined server/client code? (Read 2785 times) previous topic - next topic

SurferTim

Quote
Server server(84); //server port
Client client(server, 80);
String readString;

The second reference to server will cause an error. It was expecting
Code: [Select]
byte myserver[] = { 192, 168, 1, 10 }; // the web server for your client code to download
Server server(84); //server port for the server
Client client(myserver, 80); // use the ip address of the web server for the client


Don't use strings for this. Use a character array.
char outBuf[64];


zoomkat

Ok, something that works! I'm using the strings as I'm not that familiar with moving data in/out of arrays. Trying to stay simple for the time being. 

Code: [Select]

#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
byte myserver[] = { 208, 104, 2, 86 }; // zoomkat web page
Server server(84); //server port
Client client(myserver, 80);
String readString;

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

void setup(){

  pinMode(4, OUTPUT); //pin selected to control
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.begin(9600);
  Serial.println("server/client test 11/25/11"); // so I can keep track of what is loaded
}

void loop(){
  // check for serial input
  if (Serial.available() > 0)
  {
    byte inChar;
    inChar = Serial.read();
    if(inChar == 'e')
    {
      sendGET(); // call sendGET function
    }
  } 

  Client 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");
            client.println();
            client.println(); 
          }
          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=\"/?on\" target=\"inlineframe\">ON</a>");
            client.println("<a href=\"/?off\" target=\"inlineframe\">OFF</a>");

            //client.println("<IFRAME name=inlineframe src=\"res://D:/WINDOWS/dnserror.htm\" width=1 height=1\">");
            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("on") >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="";

        }
      }
    }
  }
}

//////////////////////////
void sendGET() //client function to send/receie GET request data.
{
  if (client.connect()) {
    Serial.println("connected");
    client.println("GET /~shb/arduino.txt HTTP/1.0");
    client.println();
  }
  else {
    Serial.println("connection failed");
    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();
    Serial.print(c);
  }

  Serial.println();
  Serial.println("disconnecting.");
  Serial.println("==================");
  Serial.println();
  client.stop();

}
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

SurferTim

There you go! And even waited for the server to close!  :)
I prefer character arrays because I can use sprintf() to do some easy numeric formatting. If the string works for you, use it.

zoomkat

I think this code is simple enough to where somebody without a lot of code experience could make some interesting arduino monitoring/control setups.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

PaulS

In terms of making it compile, reply #7 is still true.

SurferTim

#20
Nov 25, 2011, 10:00 pm Last Edit: Nov 25, 2011, 10:03 pm by SurferTim Reason: 1

In terms of making it compile, reply #7 is still true.

In terms of making it run, reply#8 is still true.

BTW, Paul, I'm not picking on you!  :)

Edit: Where do see that reference? He corrected that. That is the "myserver" change.

tek1229

#21
Nov 26, 2011, 02:42 am Last Edit: Nov 26, 2011, 02:47 am by tek1229 Reason: 1
I have code that sends data to pachube every X seconds and also is a web server.. Seems to work ok, All I did was mash the two examples together, but it seems stable and has run for 2 weeks without locking.. I'm not home so I can't post the code at the moment, Will post it later for you if that's what your looking for..
Edit: Found it from another post... here it is..

Code: [Select]
/*
  Pachube sensor client and Web server
  This sketch connects analog 0 connected to an lm34 temp sensor
Sends temp info to pachube and has a web server on port 80 using a Wiznet 810mj
Circuit:
* LM34 sensor output attached to analog in 0
* Ethernet shield attached to pins 10, 11, 12, 13
  created using pachube and web server examples originally created by Tom Igoe
  modified Nov 9th 2011 by tek1229
This code is in the public domain.
  */
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Enter a MAC address
byte ip[] = { 192,168,4,215 };  // The IP address will be dependent on your local network:
byte pachube[] = { 173,203,98,29 }; // pachube, orignal provided was incorrect..
Client client(pachube, 80); // ethernet client port
Server homeFeed(80);         // ethernet server port
long lastConnectionTime = 0;        // last time you connected to the server, in milliseconds
const int postingInterval = 20000;  //delay between updates to Pachube.com..
const byte webRefresh = 5 ;         // setting in seconds for the web page refresh-this page will auto refresh

void setup() {
  Ethernet.begin(mac, ip); // start the Ethernet connection:
  Serial.begin(9600);      // start the serial library:
  delay(1000);             // give the Ethernet shield a second to initialize:
  homeFeed.begin();         // start web server
  Serial.println("Initialized..."); // Simply a debug to show reset
         }
  void loop() {
  // Pachube timing loop.. uses generic millis timer to send data to pachube when needed
int sensorReading = (analogRead(0)*.4882)-3;  // read the analog sensor and convert to temp-adjusted for slight variance
    if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    sendData(sensorReading);   // if you're not connected, and delay set above have passed then send data to pachube
         }
    //////// Web server section /////
     
     httpRequest(sensorReading);   // http request function--see if web page is being requested
      }
      ///////////////////////// end of loop ///////////////////////////////////////////////////
     
     
  void httpRequest(String tempData) {   // this function checks for a http request and if one is requested serves up a web page with temp..
            Client client = homeFeed.available();
  if (client) {
        boolean currentLineIsBlank = true;  // an http request ends with a blank line
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.print(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.print("<font size = '6'>");
          client.print("<META HTTP-EQUIV='refresh' CONTENT='");
          client.print(webRefresh, DEC);
          client.print("'>");   
          client.println("<br />");
          client.println("<br />");
          client.print("<H1 ALIGN='CENTER'>Temperature of Garage is ");
          client.print(tempData);
          client.println("    degrees</H1");
          client.println("<br />");
          Serial.println("Web page accessed");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
   
    delay(1);   // give the web browser time to receive the data
   
    client.stop();   // close the connection:
   }
  }
             
           
void sendData(String thisData) {     // this function makes a HTTP connection to the pachube server:
   
    Serial.print(thisData); // debug
    Serial.println("  degrees ");  // debug 
    if (client.connect()) {       // if there's a successful connection:
    Serial.println("connecting to pachube...");  // debug
    client.print("PUT /api/XXXXX.csv HTTP/1.1\n"); // send the HTTP PUT request.  Change x's to your feed
    client.print("Host: www.pachube.com\n");                // fill in your feed address here:
    client.print("X-PachubeApiKey: <<<<<API KEY HERE>>>>>>\n");       // fill in your Pachube API key here:
    client.print("Content-Length: ");
    client.println(thisData.length(), DEC);

    // last pieces of the HTTP PUT request:
    client.print("Content-Type: text/csv\n");
    client.println("Connection: close\n");

    // here's the actual content of the PUT request:
    client.println(thisData);
    Serial.println("Send temp to Pachube "); // debug
    client.stop();
 
 
    lastConnectionTime = millis();           // note the time that the connection was made:
    }
  else {
     Serial.println("connection failed");   // if you couldn't make a connection:
 
  }
}

// This method calculates the number of digits in the
// sensor reading.  Since each digit of the ASCII decimal
// representation is a byte, the number of digits equals
// the number of bytes:

int getLength(int someValue) {
  int digits = 1;               // there's at least one byte:
  int dividend = someValue /10; // continually divide the value by ten,
  while (dividend > 0) {        // adding one to the digit count for each
    dividend = dividend /10;    // time you divide, until you're at 0:
    digits++;
  }
  return digits;                // return the number of digits:
}


SurferTim

#22
Nov 27, 2011, 01:41 pm Last Edit: Nov 27, 2011, 01:45 pm by SurferTim Reason: 1
@tek1229: ...and here is where you will have problems. Did you not read this thread about the server closing the connection?
http://arduino.cc/forum/index.php/topic,79949.0.html
Code: [Select]
   client.print("PUT /api/XXXXX.csv HTTP/1.1\n"); // send the HTTP PUT request.  Change x's to your feed
   client.print("Host: www.pachube.com\n");                // fill in your feed address here:
   client.print("X-PachubeApiKey: <<<<<API KEY HERE>>>>>>\n");       // fill in your Pachube API key here:
   client.print("Content-Length: ");
   client.println(thisData.length(), DEC);

   // last pieces of the HTTP PUT request:
   client.print("Content-Type: text/csv\n");
   client.println("Connection: close\n");

   // here's the actual content of the PUT request:
   client.println(thisData);
   Serial.println("Send temp to Pachube "); // debug
   client.stop(); // here is where it will eventually fail


After you send the request, you must read the server response, then wait for the server to close the connection. Then you "client.stop()". Otherwise, that connection may stay open. One socket gone...

Edit: Oops! I forgot the link. Now it is up there.

tek1229

@surfertim... I didn't have time to read the previous posts, just the original request form the op.. Not sure why mine runs so good, When I have some more spare time, I'll have to try and read this post and make adjustments to my code.. I can hit the page as many times as I want, and pachube updates all day long.. going on over 2 weeks now.. I do have to shut it down soon so I can finish the hardware and actually put it in the garage like I intended..

SurferTim

#24
Nov 29, 2011, 12:05 pm Last Edit: Nov 29, 2011, 12:08 pm by SurferTim Reason: 1
As a guess, I would say you are lucky. Some servers are not as sensitive as others. And it also depends on the timing. If you can close the connection before anything ends up in the buffer from the server, the chances are much better that the connection will close. If there is already data in the receive buffer, and the server is not finished sending, it could stay open despite the "client.stop()" on your end.

And even if it works, how do you know the server did what you requested? If you are just trying to load a web page, that might be ok. But you are trying to post data to the server. It would be nice to know that it did something with it.

Go Up