diff --git a/libraries/Ethernet/Client.cpp b/libraries/Ethernet/Client.cpp index 3b1084f0d18..96d5c7eedbd 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) > 0 ) + { + // 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..cad54a5e379 100644 --- a/libraries/Ethernet/utility/socket.cpp +++ b/libraries/Ethernet/utility/socket.cpp @@ -146,13 +146,32 @@ 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 == 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; + } - 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; }