diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp index 576201c684..e4b2d1d730 100644 --- a/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -259,7 +259,7 @@ size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) { void WiFiClient::flush() { if (_client) - _client->flush(); + _client->wait_until_sent(); } void WiFiClient::stop() diff --git a/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/libraries/ESP8266WiFi/src/WiFiUdp.cpp index c163ccef99..5e42473089 100644 --- a/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -243,8 +243,7 @@ int WiFiUDP::peek() void WiFiUDP::flush() { - if (_ctx) - _ctx->flush(); + endPacket(); } IPAddress WiFiUDP::remoteIP() diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h index 639b3587ce..b3784d25ed 100644 --- a/libraries/ESP8266WiFi/src/include/ClientContext.h +++ b/libraries/ESP8266WiFi/src/include/ClientContext.h @@ -107,7 +107,7 @@ class ClientContext if(this != 0) { DEBUGV(":ur %d\r\n", _refcnt); if(--_refcnt == 0) { - flush(); + discard_received(); close(); if(_discard_cb) { _discard_cb(_discard_cb_arg, this); @@ -277,7 +277,7 @@ class ClientContext return copy_size; } - void flush() + void discard_received() { if(!_rx_buf) { return; @@ -290,6 +290,22 @@ class ClientContext _rx_buf_offset = 0; } + void wait_until_sent() + { + // fix option 1 in + // https://github.com/esp8266/Arduino/pull/3967#pullrequestreview-83451496 + // TODO: option 2 + + #define WAIT_TRIES_MS 10 // at most 10ms + + int tries = 1+ WAIT_TRIES_MS; + + while (state() == ESTABLISHED && tcp_sndbuf(_pcb) != TCP_SND_BUF && --tries) { + _write_some(); + delay(1); // esp_ schedule+yield + } + } + uint8_t state() const { if(!_pcb) { diff --git a/libraries/Ethernet/src/EthernetUdp.cpp b/libraries/Ethernet/src/EthernetUdp.cpp index b5dcb78ccf..b9a2c867af 100644 --- a/libraries/Ethernet/src/EthernetUdp.cpp +++ b/libraries/Ethernet/src/EthernetUdp.cpp @@ -118,7 +118,7 @@ size_t EthernetUDP::write(const uint8_t *buffer, size_t size) int EthernetUDP::parsePacket() { // discard any remaining bytes in the last packet - flush(); + clear_remaining(); if (recvAvailable(_sock) > 0) { @@ -204,7 +204,7 @@ int EthernetUDP::peek() return b; } -void EthernetUDP::flush() +void EthernetUDP::clear_remaining() { // could this fail (loop endlessly) if _remaining > 0 and recv in read fails? // should only occur if recv fails after telling us the data is there, lets @@ -216,3 +216,8 @@ void EthernetUDP::flush() } } +void EthernetUDP::flush() +{ + endPacket(); +} + diff --git a/libraries/Ethernet/src/EthernetUdp.h b/libraries/Ethernet/src/EthernetUdp.h index 8a6b7ab5a8..1e928d88a4 100644 --- a/libraries/Ethernet/src/EthernetUdp.h +++ b/libraries/Ethernet/src/EthernetUdp.h @@ -49,6 +49,9 @@ class EthernetUDP : public UDP { uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed uint16_t _offset; // offset into the packet being sent uint16_t _remaining; // remaining bytes of incoming packet yet to be processed + +protected: + void clear_remaining(); public: EthernetUDP(); // Constructor