Ethernet Reset Problems

The usual apologies for perhaps posting something that has already been dealt with elsewhere!

I am just learning the Arduino Ethernet stuff (although I have been doing Arduino stuff for a few months) and I am just trying to build a simple POP3 email checker – i.e. – log into my POP3 server and tell me if I have any emails and how many I have and indicate this physically somehow with lights or on a serial display.

I am using a brand new Arduino Duemilanove and an Arduino Ethernet shield and Arduino 0017 and building on the Client test code found on the Arduino Ethernet Library reference.

What I have found when I started running this code was that it would go through once, but when I tried to get it to loop continuously it would hang up. Eventually, I set up a simple PHP server program on my PC using some code off of the PHP site and tested with it to see what was going on. What PHP tells me is that on the 2nd loop, it gives me:

PHP Warning: socket_read(): unable to read from socket [10054]: An existing connection was forcibly closed by the remote host.

So, I hooked it up to Wireshark and I can see that the Arduino is definitely sending a reset packet that kills the connection:

2654 41.395707 192.168.0.171 192.168.0.172 TCP ndmp > blackjack [ACK] Seq=146 Ack=35 Win=64206 Len=0
3947 75.790782 192.168.0.172 192.168.0.171 TCP [TCP Port numbers reused] blackjack > ndmp [SYN] Seq=0 Win=2048 Len=0 MSS=1460
3948 75.790807 192.168.0.171 192.168.0.172 TCP [TCP ACKed lost segment] ndmp > blackjack [ACK] Seq=1 Ack=25281714 Win=64206 Len=0
3949 75.790849 192.168.0.172 192.168.0.171 TCP blackjack > ndmp [RST] Seq=25281714 Win=0 Len=0
3955 75.993016 192.168.0.172 192.168.0.171 TCP blackjack > ndmp [SYN] Seq=0 Win=2048 Len=0 MSS=1460
3956 75.993054 192.168.0.171 192.168.0.172 TCP ndmp > blackjack [RST, ACK] Seq=533015016 Ack=1 Win=0 Len=0

I have tried various suggestions for changes to the Client.h and client.cpp files, but to no avail.

Anyway, this is annoying since it really seems like either there is something wrong with the sample code from Arduino or something wrong with the Ethernet library! Lots of people seem to be discussing it on the boards, but I can't get through to a definite fix. Any suggestions anyone?

thanks in advance!

Can you post the code that is giving you the problem?

Hello,

Right now, I am just trying to work through the sample code from the Arduino site slightly modified for my local IPs & ports:

#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192.168.0.172 };
byte server[] = { 192, 168, 0, 171 }; // My PHP server

Client client(server, 10000);

void setup()
{
  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  delay(1000);

  Serial.println("connecting...");

  if (client.connect()) {
    Serial.println("connected");
    client.println("GET /search?q=arduino HTTP/1.0");
    client.println();
  } else {
    Serial.println("connection failed");
  }
}

void loop()
{
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    for(;;)
      ;
  }
}

The simple socket server I am using for testing is:

<?php
error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting
 * as it comes in. */
ob_implicit_flush();

$address = '192.168.0.171';
$port = 10000;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}

if (socket_bind($sock, $address, $port) === false) {
    echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}

if (socket_listen($sock, 5) === false) {
    echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}

do {
    if (($msgsock = socket_accept($sock)) === false) {
        echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    /* Send instructions. */
    $msg = "\nWelcome to the PHP Test Server. \n" .
        "To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
    socket_write($msgsock, $msg, strlen($msg));

    do {
        if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
            echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n";
            break 2;
        }
        if (!$buf = trim($buf)) {
            continue;
        }
        if ($buf == 'quit') {
            break;
        }
        if ($buf == 'shutdown') {
            socket_close($msgsock);
            break 2;
        }
        $talkback = "PHP: You said '$buf'.\n";
        socket_write($msgsock, $talkback, strlen($talkback));
        echo "$buf\n";
    } while (true);
    socket_close($msgsock);
} while (true);

socket_close($sock);
?>

Works like a charm ONCE, but trying to run it more than once it does the reset thing.

thanks!

Yes, I think they did that on purpose so that it only grabs the info once but gives you an idea on how to do it. Anything in setup() will only run once, and the loop(), well it loops. You'll need to decide how you want to trigger your connection be it interval based or from some other input.

I have tried looping it, but whenever it goes to repeat it resets the connection. I have also tried a variety of delay() statements.

You'll need to connect again before it will pull data, this is what is currently in the setup() area. If you post your code attempt, we can help you out more.

I have tried a bunch of variants, but they come down to this - putting the connection info into the loop and/or commenting out the "for(;;)".

#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 0, 172 };
byte server[] = { 192, 168, 0, 171 }; // Google

void setup()
{
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  delay(1000);

}

void loop()
{

  Client client(server, 10000);
  
   Serial.println("connecting...");

  if (client.connect()) {
    Serial.println("connected");
  delay(500);
    client.println("GET /search?q=arduino HTTP/1.0");
   delay(500); 
    client.println();
  } else {
    Serial.println("connection failed");
  } 
  
   if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.flush();
    client.stop();
//    for(;;)
//      ;
  }
  
  delay(5000);
  
}

Thanks for looking at this. It does seem like a few people have run into various probelms with the Ethernet library.

This is untested and after a few beers, but it should try to connect every 10 seconds. Hopefully, it will give you some ideas at least.

#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192.168.0.172 };
byte server[] = { 192, 168, 0, 171 }; // My PHP server

Client client(server, 10000);

long updateTimer;
boolean clientConnected = false;

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

void loop()
{
  updateClient();
  checkAvail();
}

void updateClient()
{
  if ((millis() - updateTimer) > 10000)
  {
    Ethernet.begin(mac, ip);
    Serial.println("connecting...");
    delay(1000);
    if (client.connect())
    {
      Serial.println("connected");
      client.println("GET /search?q=arduino HTTP/1.0");
      client.println();
      clientConnected = true;
    }
    else
    {
      Serial.println("connection failed");
    }
    updateTimer = millis();
  }
}

void checkAvail()
{
  if (clientConnected)
  {
    if (client.available())
    {
      char c = client.read();
      Serial.print(c);
    }
    if (!client.connected())
    {
      Serial.println();
      Serial.println("disconnecting.");
      client.stop();
      clientConnected = false;
    }
  }
}

Excellent, this works fine when I try it with the Google IP address given in the original Arduino Ethernet Client example (64.233.187.99), but won't work with my test PHP socket application, so that shows there is something wrong with my test socket app - perhaps timing or something! Now I can adapt it to the POP3 example I wanted to try originally then fool around with the PHP server later.

Forgive my ignorance, but why would this work with the code in functions rather than the main loop - apart from the fact that it is neater?

Also, the compiler warned me that "byte ip[] = { 192.168.0.172 };" needs to be byte ip[] = { 192, 168, 0, 172 };! Watch out for coding & beers! ;D

Again, thanks very much for the help! This really should be the Ethernet client demo code example!

regards,

torchris

OK, it took about 3 seconds to interset the POP3 commands and it works like a charm!

For those who want to try interfacing to a POP3 server, here is the basic code - you just need to insert your POP3 server IP, username & password:

#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,0,172 };
byte server[] = { XXX, XXX, XXX, XXX }; // IP address of your POP3 server

Client client(server, 110);

long updateTimer;
boolean clientConnected = false;

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

void loop()
{
  updateClient();
  checkAvail();
}

void updateClient()
{
  if ((millis() - updateTimer) > 10000)
  {
    Ethernet.begin(mac, ip);
    Serial.println("connecting...");
    delay(1000);
    if (client.connect())
    {
      Serial.println("connected");
      client.println("user user.name"); //Insert your usual email login name
      client.println("pass YourEmailPassword"); //And your password here
      client.println("quit");
      client.println();
      clientConnected = true;
    }
    else
    {
      Serial.println("connection failed");
    }
    updateTimer = millis();
  }
}

void checkAvail()
{
  if (clientConnected)
  {
    if (client.available())
    {
      char c = client.read();
      Serial.print(c);
    }
    if (!client.connected())
    {
      Serial.println();
      Serial.println("disconnecting.");
      client.stop();
      clientConnected = false;
    }
  }
}

This will then output to the serial monitor:

connecting...
connected
+OK hello from popgate 2.43 on pop108.xxx.xxx.xxx.xxx.xxx
+OK password required.
+OK maildrop ready, 0 messages (0 octets) (16335883)
+OK server signing off.

disconnecting.

It will loop through this nicely. Next up, I will need to figure out how to parse the "XX Messages" and have that do something useful! :slight_smile:

Glad to hear you got it going.

Greetings! I'm trying out your code and have modified it to work with a BlinkM instead of a regular LED however, I am unable to connect. I suspect it might be due to the fact that I'm attempting to login to gmail's pop server, which requires SSL auth. Any ideas why I'm getting "connection failed"?

Thanks!

Jyro

You could try using port 995 which is what their web page recommends:

I am pretty sure that won't work either because SSL is encrypted and I am pretty sure there isn't a library for Arduino to support that.

Any thoughts from people smarter than me are welcome! :slight_smile:

regards,

torchris

BTW - Great idea using the BlinkM! I was thinking about using a servo or something to create like a guage of my email, but I haven't gotten around to trying that yet. You can read more about my complete project on my blog:

http://opensourceprojects-torchris.blogspot.com/

  • torchris