aboutsummaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
authorDavid A. Mellis <d.mellis@arduino.cc>2009-04-26 14:58:39 +0000
committerDavid A. Mellis <d.mellis@arduino.cc>2009-04-26 14:58:39 +0000
commit3531cb49f43e067779963beb2b7fc4b098ad769f (patch)
treec4c884eed06b1659208359c1b7ba15258ad13d63 /libraries
parent0681fc1f177f7c94b4e98bb0931a5efda50f32b0 (diff)
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.
Diffstat (limited to 'libraries')
-rw-r--r--libraries/Ethernet/Client.cpp47
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() {