diff options
Diffstat (limited to 'libraries/Ethernet/Client.cpp')
-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() { |