diff options
| -rw-r--r-- | libraries/Ethernet/Client.cpp | 47 | 
1 files changed, 37 insertions, 10 deletions
| diff --git a/libraries/Ethernet/Client.cpp b/libraries/Ethernet/Client.cpp index 51096db..13cf6bf 100644 --- a/libraries/Ethernet/Client.cpp +++ b/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() { | 
