From 81b6c69f295fc58f928f758916540d1daf5d4bc9 Mon Sep 17 00:00:00 2001 From: amcewen Date: Sun, 2 Jan 2011 22:21:24 +0000 Subject: [PATCH 1/2] An improved patch for the Client part of issue 416 (adding a multi-byte read). This one moves all of the checking into recv, so that single-byte reads also benefit. It also returns -1 if there's no data available unless we've reached EOF, in which case it returns 0. --- libraries/Ethernet/Client.cpp | 17 ++++++++++++++--- libraries/Ethernet/Client.h | 1 + libraries/Ethernet/utility/socket.cpp | 12 ++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/libraries/Ethernet/Client.cpp b/libraries/Ethernet/Client.cpp index 3b1084f0d18..51cb5eb145b 100644 --- a/libraries/Ethernet/Client.cpp +++ b/libraries/Ethernet/Client.cpp @@ -77,14 +77,25 @@ int Client::available() { int Client::read() { uint8_t b; - if (!available()) + if ( recv(_sock, &b, 1) ) + { + // recv worked + return b; + } + else + { + // No data available return -1; - recv(_sock, &b, 1); - return b; + } +} + +int Client::read(uint8_t *buf, size_t size) { + return recv(_sock, buf, size); } int Client::peek() { uint8_t b; + // Unlike recv, peek doesn't check to see if there's any data available, so we must if (!available()) return -1; ::peek(_sock, &b); diff --git a/libraries/Ethernet/Client.h b/libraries/Ethernet/Client.h index f0080bdf6c1..8725f158a9c 100644 --- a/libraries/Ethernet/Client.h +++ b/libraries/Ethernet/Client.h @@ -17,6 +17,7 @@ class Client : public Stream { virtual void write(const uint8_t *buf, size_t size); virtual int available(); virtual int read(); + virtual int read(uint8_t *buf, size_t size); virtual int peek(); virtual void flush(); void stop(); diff --git a/libraries/Ethernet/utility/socket.cpp b/libraries/Ethernet/utility/socket.cpp index 628bca80851..57cdf0d4cc9 100644 --- a/libraries/Ethernet/utility/socket.cpp +++ b/libraries/Ethernet/utility/socket.cpp @@ -146,13 +146,17 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len) */ uint16_t recv(SOCKET s, uint8_t *buf, uint16_t len) { - uint16_t ret=0; + // Check how much data is available + uint16_t ret = W5100.getRXReceivedSize(s); + if (ret > len) + { + ret = len; + } - if ( len > 0 ) + if ( ret > 0 ) { - W5100.recv_data_processing(s, buf, len); + W5100.recv_data_processing(s, buf, ret); W5100.execCmdSn(s, Sock_RECV); - ret = len; } return ret; } From 983d8af8140f09fd3975d5deef64244102912550 Mon Sep 17 00:00:00 2001 From: amcewen Date: Sun, 2 Jan 2011 22:49:11 +0000 Subject: [PATCH 2/2] Final changes for the Client part of issue 416, which actually include the corrent return values. This should have been in the previous commit, but I'm still getting my head round git. --- libraries/Ethernet/Client.cpp | 2 +- libraries/Ethernet/utility/socket.cpp | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libraries/Ethernet/Client.cpp b/libraries/Ethernet/Client.cpp index 51cb5eb145b..96d5c7eedbd 100644 --- a/libraries/Ethernet/Client.cpp +++ b/libraries/Ethernet/Client.cpp @@ -77,7 +77,7 @@ int Client::available() { int Client::read() { uint8_t b; - if ( recv(_sock, &b, 1) ) + if ( recv(_sock, &b, 1) > 0 ) { // recv worked return b; diff --git a/libraries/Ethernet/utility/socket.cpp b/libraries/Ethernet/utility/socket.cpp index 57cdf0d4cc9..cad54a5e379 100644 --- a/libraries/Ethernet/utility/socket.cpp +++ b/libraries/Ethernet/utility/socket.cpp @@ -148,7 +148,22 @@ uint16_t recv(SOCKET s, uint8_t *buf, uint16_t len) { // Check how much data is available uint16_t ret = W5100.getRXReceivedSize(s); - if (ret > len) + if ( ret == 0 ) + { + // No data available. + uint8_t status = W5100.readSnSR(s); + if ( s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::CLOSE_WAIT ) + { + // The remote end has closed its side of the connection, so this is the eof state + ret = 0; + } + else + { + // The connection is still up, but there's no data waiting to be read + ret = -1; + } + } + else if (ret > len) { ret = len; }