From 5e89129ba50e361b88afe98b03d4fae55b7526d8 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Sun, 26 Apr 2009 14:58:39 +0000 Subject: [PATCH] Fixes to the way the Client class connects and disconnects, as well as checks of whether or not the socket is valid in various functions. --- hardware/libraries/Ethernet/Client.cpp | 47 ++++++++++++++++++++------ readme.txt | 10 ++++++ todo.txt | 8 +++-- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/hardware/libraries/Ethernet/Client.cpp b/hardware/libraries/Ethernet/Client.cpp index 51096dbec..13cf6bf54 100644 --- a/hardware/libraries/Ethernet/Client.cpp +++ b/hardware/libraries/Ethernet/Client.cpp @@ -5,6 +5,8 @@ extern "C" { #include "string.h" } +#include "WProgram.h" + #include "Ethernet.h" #include "Client.h" #include "Server.h" @@ -18,14 +20,18 @@ Client::Client(uint8_t sock) { Client::Client(uint8_t *ip, uint16_t port) { _ip = ip; _port = port; + _sock = 255; } uint8_t Client::connect() { - _sock = 255; + if (_sock != 255) + return 0; for (int i = 0; i < MAX_SOCK_NUM; i++) { - if (getSn_SR(i) == SOCK_CLOSED) { + uint8_t s = getSn_SR(i); + if (s == SOCK_CLOSED || s == SOCK_FIN_WAIT) { _sock = i; + break; } } @@ -33,13 +39,14 @@ uint8_t Client::connect() { return 0; _srcport++; - - socket(_sock, Sn_MR_TCP, 1024 + _srcport, 0); + if (_srcport + 1024 == 0) _srcport = 0; + socket(_sock, Sn_MR_TCP, _srcport + 1024, 0); if (!::connect(_sock, _ip, _port)) return 0; while (status() != SOCK_ESTABLISHED) { + delay(1); if (status() == SOCK_CLOSED) return 0; } @@ -48,19 +55,24 @@ uint8_t Client::connect() { } void Client::write(uint8_t b) { - send(_sock, &b, 1); + if (_sock != 255) + send(_sock, &b, 1); } void Client::write(const char *str) { - send(_sock, (const uint8_t *)str, strlen(str)); + if (_sock != 255) + send(_sock, (const uint8_t *)str, strlen(str)); } void Client::write(const uint8_t *buf, size_t size) { - send(_sock, buf, size); + if (_sock != 255) + send(_sock, buf, size); } int Client::available() { - return getSn_RX_RSR(_sock); + if (_sock != 255) + return getSn_RX_RSR(_sock); + return 0; } int Client::read() { @@ -77,14 +89,29 @@ void Client::flush() { } void Client::stop() { - close(_sock); + if (_sock == 255) + return; + + // attempt to close the connection gracefully (send a FIN to other side) disconnect(_sock); + unsigned long start = millis(); + + // wait a second for the connection to close + while (status() != SOCK_CLOSED && millis() - start < 1000) + delay(1); + + // if it hasn't closed, close it forcefully + if (status() != SOCK_CLOSED) + close(_sock); + EthernetClass::_server_port[_sock] = 0; + _sock = 255; } uint8_t Client::connected() { uint8_t s = status(); - return !(s == SOCK_LISTEN || s == SOCK_CLOSED || (s == SOCK_CLOSE_WAIT && !available())); + return !(s == SOCK_LISTEN || s == SOCK_CLOSED || s == SOCK_FIN_WAIT || + (s == SOCK_CLOSE_WAIT && !available())); } uint8_t Client::status() { diff --git a/readme.txt b/readme.txt index 9b82d4ad3..120e7e6d8 100644 --- a/readme.txt +++ b/readme.txt @@ -46,6 +46,16 @@ Processing and Wiring. UPDATES +0016 + +[core / libraries] +* Adding write(str) and write(buf, size) methods to Print, Serial, and the + Ethernet library Client and Server classes. This allows for more efficient + (fewer packet) Ethernet communication. (Thanks to mikalhart.) +* Improvements to the way the Ethernet library Client class connects and + disconnects. Should reduce or eliminate failed connections and long + timeouts. (Thanks to Bruce Luckcuck.) + 0015 - 2009.03.26 [core / libraries] diff --git a/todo.txt b/todo.txt index 6fe1390e1..28feef6e7 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,4 @@ -0015 arduino +0016 arduino AVR @@ -29,8 +29,11 @@ Add OneWire library. Add pulseOut(), etc. functions from Wiring. Switch to ServoTimer2 library? http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1222201226/0#5 Add ContinuousServo library that inherits from Servo? -LiquidCrystal library: support going to the next line with println(). +LiquidCrystal library: + - support going to the next line with println(). + - proper software initialization of the LCD: http://web.alfredstate.edu/weimandn/arduino/liquidCrystal_library/liquidCrystal.cpp Ethernet library: + - client.connect() returns 0 when connection is successful? http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238295170 - call Server.begin() from Ethernet.begin() instead of in user's sketch? - add method for receiving notification of new client connections to a server - add method for receiving notification of data written to a client @@ -44,6 +47,7 @@ Consider moving millis() to timer 1, and configuring it so the interrupt is gene COMPUTER +Move selection of Linux look and feel from Base.java to arduino.sh script. Check RAM usage of sketches: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1224729260/0#0 Improve preprocessing of sketches: - Better determine which header files are included (not commented out).