Go Down

Topic: Inconsistent HTTP Connnection (Read 6879 times) previous topic - next topic

SurferTim

That was my bad.

Which code are you using now? Are you still trying your original code? Or zoomkat's?

jamgood96

I haven't had a chance to work on this project for the past few days, but I tried using my original code (with a few modifications) as well as zoomkat's. Both seem to give me mixed results as far as connectivity. With zoomkat's, sometimes it connects and downloads a page immediately after I press 'e', other times it takes around 20 seconds before it says connection failed.

I originally had things set up in a for loop so that it would keep trying over and over again. This seemed to provide okay results, but also seemed like a work-around with addressing the actual problem.

SurferTim

This loads www.google.com every 10 seconds. Don't do that to Google too long. Besides, it is a big page and takes a while to display at 9600 baud. Change the server ip to yours.
Code: [Select]
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,2,2);
IPAddress gateway(192, 168, 2, 1);
IPAddress subnet(255, 255, 255, 0);

IPAddress server(74,125,227,16); // Google

EthernetClient client;
int totalCount = 0;
int loopCount = 0;

void setup() {
  Serial.begin(9600);

  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  delay(2000);
  Serial.println("Ready");
}

void loop()
{
  if(loopCount < 10)
  {
    delay(1000);
  }
  else
  {
    loopCount = 0;

    if(!getPage(server,"/")) Serial.print("Fail ");
    else Serial.print("Pass ");
    totalCount++;
    Serial.println(totalCount,DEC);
  }   

  loopCount++;
}

byte getPage(IPAddress ipBuf,char *page)
{
  int inChar;
  char outBuf[64];

  Serial.print("connecting...");

  if(client.connect(ipBuf,80))
  {
    Serial.println("connected");

    sprintf(outBuf,"GET %s HTTP/1.0\r\n\r\n",page);
    client.write(outBuf);
  }
  else
  {
    Serial.println("failed");
    return 0;
  }

  while(client.connected())
  {
    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
    }
  }

  Serial.println();

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

  return 1;
}


jamgood96

Hmmm, well that seems to work so far. I've only had a few minutes this morning to play, but I haven't gotten any failed attempts (except for when I forgot to change the IP).

So what's different? Why is this one connecting fine whereas the others weren't?

SurferTim

#19
Apr 10, 2012, 08:27 pm Last Edit: Apr 10, 2012, 10:31 pm by SurferTim Reason: 1

Hmmm, well that seems to work so far. I've only had a few minutes this morning to play, but I haven't gotten any failed attempts (except for when I forgot to change the IP).

So what's different? Why is this one connecting fine whereas the others weren't?


The others were not mine.  :)

edit: There are some reasons mine works better. I know how tcp works. If you look at the getPage() function, you will notice the "while(client.connected()) while(client.available())" loops.

If you are downloading a big page (like Google's home page), you will get several packets. That loop will check client.available(), and for a while, it will be zero. Then it will be about 1400. Your goal is to empty that rx buffer as fast as you can. Get client.available() to zero. Then it may be zero again for a few checks, then it will be 1400 again (another packet).

The client.connected() will return true until you have emptied the rx buffer of the final packet, so as long as client.available() returns non-zero, you are connected.

jamgood96

Yeah, that's exactly what I was thinking it did...  XD

Thanks so much! I'll keep you posted if I run into errors with this, but so far so good.

zoomkat

Quote
The others were not mine.


I can't beleve this code is yours! It doesn't contain the magic pixie dust (below) that makes all things work!  :)  I notice the code does have a fat 2000ms delay that has been used in older code.

Code: [Select]
void setup()
{
   Serial.begin(9600);

   // disable the SD SPI interface
   pinMode(4,OUTPUT);
   digitalWrite(4,HIGH);

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

SurferTim


Quote
The others were not mine.


I can't beleve this code is yours! It doesn't contain the magic pixie dust (below) that makes all things work!  :)  I notice the code does have a fat 2000ms delay that has been used in older code.

Code: [Select]
void setup()
{
   Serial.begin(9600);

   // disable the SD SPI interface
   pinMode(4,OUTPUT);
   digitalWrite(4,HIGH);

   // rest of your setup
}



You did not pay attention, because it does have the magic pixie dust!  :)

zoomkat

#23
Apr 11, 2012, 06:19 am Last Edit: Apr 11, 2012, 06:21 am by zoomkat Reason: 1
Quote
You did not pay attention, because it does have the magic pixie dust!  


Oh, my bad! Just as a test, I removed the pixie dust from your code like below, and ate some salted peanuts instead. The code made 17 successful passes, so salted peanuts work too!  :)

Code: [Select]

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

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress server(74,125,227,16); // Google

EthernetClient client;
int totalCount = 0;
int loopCount = 0;

void setup() {
 Serial.begin(9600);

 //pinMode(4,OUTPUT);
 //digitalWrite(4,HIGH);

 Ethernet.begin(mac);
 delay(2000);
 Serial.println("Ready");
}
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

SurferTim

#24
Apr 11, 2012, 01:17 pm Last Edit: Apr 11, 2012, 01:50 pm by SurferTim Reason: 1
I used to think that too. Here is an old thread that we both were involved in. Read reply #28.
http://arduino.cc/forum/index.php/topic,75324.0.html
I don't think salted peanuts would have helped there. The magic pixie dust did.

The OP's question was why mine was working and the others weren't. This is part of the reason why.

edit: If you want to read the posts where I was being you and eating salted peanuts, read replies 7,20,and 26.

cantore

One question? How can we be sure that the program will never stop on the line
Code: [Select]

while(client.connected()


If the client connection does not end we will never go out of the while loop

SurferTim


One question? How can we be sure that the program will never stop on the line
Code: [Select]

while(client.connected()


If the client connection does not end we will never go out of the while loop


Good question. There is the possibility of a lockup there if the connection breaks. Here is the thread with the discussion and the patch for a 10 second timeout.
http://arduino.cc/forum/index.php/topic,102879.msg778413.html#msg778413



This loads www.google.com every 10 seconds. Don't do that to Google too long. Besides, it is a big page and takes a while to display at 9600 baud. Change the server ip to yours.
Code: [Select]
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,2,2);
IPAddress gateway(192, 168, 2, 1);
IPAddress subnet(255, 255, 255, 0);

IPAddress server(74,125,227,16); // Google

EthernetClient client;
int totalCount = 0;
int loopCount = 0;

void setup() {
  Serial.begin(9600);

  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  delay(2000);
  Serial.println("Ready");
}

void loop()
{
  if(loopCount < 10)
  {
    delay(1000);
  }
  else
  {
    loopCount = 0;

    if(!getPage(server,"/")) Serial.print("Fail ");
    else Serial.print("Pass ");
    totalCount++;
    Serial.println(totalCount,DEC);
  }   

  loopCount++;
}

byte getPage(IPAddress ipBuf,char *page)
{
  int inChar;
  char outBuf[64];

  Serial.print("connecting...");

  if(client.connect(ipBuf,80))
  {
    Serial.println("connected");

    sprintf(outBuf,"GET %s HTTP/1.0\r\n\r\n",page);
    client.write(outBuf);
  }
  else
  {
    Serial.println("failed");
    return 0;
  }

  while(client.connected())
  {
    while(client.available())
    {
      inChar = client.read();
      Serial.write(inChar);
    }
  }

  Serial.println();

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

  return 1;
}




The server I'm trying to reach is in a virtual hosting environment so in addition to the ip address, I need to specify the host I want to connect to. Do you have any advice on where that would be included if one wanted to make that tweak?

SurferTim

#29
May 28, 2012, 10:59 pm Last Edit: May 28, 2012, 11:01 pm by SurferTim Reason: 1
It is sent on a line by itself after the GET, followed by a double CR-LF.
Code: [Select]
 if(client.connect(ipBuf,80))
 {
   Serial.println("connected");
   // Insert it here.
   sprintf(outBuf,"GET %s HTTP/1.0\r\nHost: www.mydomain.com\r\n\r\n",page);
   client.write(outBuf);
 }


edit: Insure outBuf has sufficient memory allocated to hold all that.

Go Up