diff --git a/libraries/ESP8266WiFi/src/WiFiClient.cpp b/libraries/ESP8266WiFi/src/WiFiClient.cpp
index 6af42318a7..84977d87ed 100644
--- a/libraries/ESP8266WiFi/src/WiFiClient.cpp
+++ b/libraries/ESP8266WiFi/src/WiFiClient.cpp
@@ -344,3 +344,29 @@ void WiFiClient::stopAllExcept(WiFiClient* except)
         }
     }
 }
+
+
+void WiFiClient::keepAlive (uint16_t idle_sec, uint16_t intv_sec, uint8_t count)
+{
+    _client->keepAlive(idle_sec, intv_sec, count);
+}
+
+bool WiFiClient::isKeepAliveEnabled () const
+{
+    return _client->isKeepAliveEnabled();
+}
+
+uint16_t WiFiClient::getKeepAliveIdle () const
+{
+    return _client->getKeepAliveIdle();
+}
+
+uint16_t WiFiClient::getKeepAliveInterval () const
+{
+    return _client->getKeepAliveInterval();
+}
+
+uint8_t WiFiClient::getKeepAliveCount () const
+{
+    return _client->getKeepAliveCount();
+}
diff --git a/libraries/ESP8266WiFi/src/WiFiClient.h b/libraries/ESP8266WiFi/src/WiFiClient.h
index 10204a705d..5dcc43186f 100644
--- a/libraries/ESP8266WiFi/src/WiFiClient.h
+++ b/libraries/ESP8266WiFi/src/WiFiClient.h
@@ -30,6 +30,10 @@
 
 #define WIFICLIENT_MAX_PACKET_SIZE 1460
 
+#define TCP_DEFAULT_KEEPALIVE_IDLE_SEC          7200 // 2 hours
+#define TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC      75   // 75 sec
+#define TCP_DEFAULT_KEEPALIVE_COUNT             9    // fault after 9 failures
+
 class ClientContext;
 class WiFiServer;
 
@@ -85,6 +89,13 @@ class WiFiClient : public Client, public SList<WiFiClient> {
   static void stopAll();
   static void stopAllExcept(WiFiClient * c);
 
+  void     keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT);
+  bool     isKeepAliveEnabled () const;
+  uint16_t getKeepAliveIdle () const;
+  uint16_t getKeepAliveInterval () const;
+  uint8_t  getKeepAliveCount () const;
+  void     disableKeepAlive () { keepAlive(0, 0, 0); }
+
 protected:
 
   static int8_t _s_connected(void* arg, void* tpcb, int8_t err);
diff --git a/libraries/ESP8266WiFi/src/include/ClientContext.h b/libraries/ESP8266WiFi/src/include/ClientContext.h
index b3784d25ed..b2628f8032 100644
--- a/libraries/ESP8266WiFi/src/include/ClientContext.h
+++ b/libraries/ESP8266WiFi/src/include/ClientContext.h
@@ -43,6 +43,9 @@ class ClientContext
         tcp_sent(pcb, &_s_sent);
         tcp_err(pcb, &_s_error);
         tcp_poll(pcb, &_s_poll, 1);
+
+        // not enabled by default for 2.4.0
+        //keepAlive();
     }
 
     err_t abort()
@@ -341,6 +344,38 @@ class ClientContext
         return _write_from_source(new BufferedStreamDataSource<ProgmemStream>(stream, size));
     }
 
+    void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT)
+    {
+        if (idle_sec && intv_sec && count) {
+            _pcb->so_options |= SOF_KEEPALIVE;
+            _pcb->keep_idle = (uint32_t)1000 * idle_sec;
+            _pcb->keep_intvl = (uint32_t)1000 * intv_sec;
+            _pcb->keep_cnt = count;
+        }
+        else
+            _pcb->so_options &= ~SOF_KEEPALIVE;
+    }
+
+    bool isKeepAliveEnabled () const
+    {
+        return !!(_pcb->so_options & SOF_KEEPALIVE);
+    }
+
+    uint16_t getKeepAliveIdle () const
+    {
+        return isKeepAliveEnabled()? (_pcb->keep_idle + 500) / 1000: 0;
+    }
+
+    uint16_t getKeepAliveInterval () const
+    {
+        return isKeepAliveEnabled()? (_pcb->keep_intvl + 500) / 1000: 0;
+    }
+
+    uint8_t getKeepAliveCount () const
+    {
+        return isKeepAliveEnabled()? _pcb->keep_cnt: 0;
+    }
+
 protected:
 
     bool _is_timeout()