user56610: I have a Keyes Espressif ESP8266 NodeMCU, I have two LEDs that I want to control which are connected to the ESP. When I open the webpage http://10.0.0.5/5 after uploading the sketch it works fine. If I don't open and close the website before ~ 02:30[mm:ss] the server becomes unreachable even if I close the existing connection and open a new connection in a new tab the same error yields: ERR_CONNECTION_TIMED_OUT 
If I don't open a web page before ~ 02:30[mm:ss] I also receive error ERR_CONNECTION_TIMED_OUT
The web server is only made available when I hard reset the board then the same rules apply as above. 
ESP.getFullVersion() outputs: 
SDK:2.2.1(cfd48f3)/Core:2.5.1=20501000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1-7-g82abda3/BearSSL:a143020

Question: 
How can I make the web server accessible constantly? 
With the help of @Juraj I tried changing to SDK V3 which made no difference I also tried: 

All lwip variants

My Code: 

// Load Wi-Fi library
#include <ESP8266WiFi.h>

// Replace with your network credentials
const char* ssid     = "DO_231455";
const char* password = "0828842107";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
String output5State = "off";
String output4State = "off";

// Assign output variables to GPIO pins
const int output5 = 16;
const int output4 = 4;

void setup() {
  Serial.begin(115200);

  // Initialize the output variables as outputs
  pinMode(output5, OUTPUT);
  pinMode(output4, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output5, LOW);
  digitalWrite(output4, LOW);

  Serial.print(ESP.getFullVersion());
  //WiFi.disconnect() ;
  //WiFi.persistent(false);
  //WiFi.setSleepMode(WIFI_NONE_SLEEP);
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients
  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // turns the GPIOs on and off
            if (header.indexOf("GET /5/on") >= 0) {
              Serial.println("GPIO 5 on");
              output5State = "on";
              digitalWrite(output5, HIGH);
            } else if (header.indexOf("GET /5/off") >= 0) {
              Serial.println("GPIO 5 off");
              output5State = "off";
              digitalWrite(output5, LOW);
            } else if (header.indexOf("GET /4/on") >= 0) {
              Serial.println("GPIO 4 on");
              output4State = "on";
              digitalWrite(output4, HIGH);
            } else if (header.indexOf("GET /4/off") >= 0) {
              Serial.println("GPIO 4 off");
              output4State = "off";
              digitalWrite(output4, LOW);
            }

            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons 
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #77878A;}</style></head>");

            // Web Page Heading
            client.println("<body><h1>ESP8266 Web Server</h1>");

            // Display current state, and ON/OFF buttons for GPIO 5  
            client.println("<p>GPIO 5 - State " + output5State + "</p>");
            // If the output5State is off, it displays the ON button       
            if (output5State=="off") {
              client.println("<p><a href=\"/5/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/5/off\"><button class=\"button button2\">OFF</button></a></p>");
            } 

            // Display current state, and ON/OFF buttons for GPIO 4  
            client.println("<p>GPIO 4 - State " + output4State + "</p>");
            // If the output4State is off, it displays the ON button       
            if (output4State=="off") {
              client.println("<p><a href=\"/4/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/4/off\"><button class=\"button button2\">OFF</button></a></p>");
            }
            client.println("</body></html>");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

Worth noting (while debugging):
The new client disconnects.


user56610: The short answer: Config a static IP!
After looking at Git Issue #2371 I found out that I need to create a static IP address to fix this issue. I can do this by inserting WiFi.config(ip, gateway, subnet) just before WiFi.mode(WIFI_STA) in the code above. 

First I found the information gateway & subnet I needed by opening the command prompt on a computer that's connected to the access point(router) as the one connected to the ESP8266 which functions in station mode. I did this on Windows by searching Command Prompt then typing ipconfig to obtain the following information: 


Replace the points with commas! See this references for more information regarding other parameters and DNS.


To create an IP address you need to see your IP address in the red square in the picture above taken from the command prompt. The first three octects (numbers) of your router IP (probably 10.0.0.x, 192.168.0.x, or 192.168.1.x) must match your chosen static IP. For my example the numbers to match would be 10.0.0.
Next, I needed to obtain the DCHP range for my router. My router is a Netgear Wireless ADSL2+ Modem Router DG834Gv5. To obtain the range I needed to access my router settings. To access this I looked for an HTTP link under the router. For my router it was http://10.0.0.2 along with the username and password which was admin, admin respectively. This is what it looks like: 


This will vary according to your router - Then I went into Advanced settings and saw the DHCP range. This is an error on my part noted by @djsfantasi. Please see his answer regarding DHCP range selection.The new static IP needs to be within the DHCP range According to one of the comments brendanmatkin made in Git Issue #2371 the last number of my static IP (which is ZZ in WW.XX.YY.ZZ) needs to be outside of this range. For me it didn't work, it worked when I used a value inside this range but brendanmatkin knows much more than me, I'm just a novice. There might be implications that I am not aware of so I think it's worth looking into. A DHCP range looks like this below: 

My inserted code looks like this below:
void setup(void) {
  .
  .
  .
  Serial.begin(115200);
  //WiFi.disconnect();  //Prevent connecting to wifi based on previous configuration
  IPAddress ip(10,0,0,15); // this 3 lines for a fix IP-address
  IPAddress gateway(10,0,0,2); 
  IPAddress subnet(255,255,255,0);
  //WiFi.hostname("ESP8266");      // DHCP Hostname (useful for finding device for static lease)
  WiFi.config(ip, gateway, subnet);
  //Station mode:
  WiFi.mode(WIFI_STA); 
  .
  .
  .
}

Please comment for more info :)
Additional information and changes I've made to IDE: 
OS : Windows 8.1 
IDE : Arduino IDE V1.9.8
Board : Keyes ESP8266
Arduino IDE > Tools >Board (in boards manager) : Generic ESP8266 Board   
Arduino IDE > Tools >lwip : V2 Low Memory
Arduino IDE > Tools >Esp FW:"nonos.." : nonos-sdk pr-3(known issues)*
Power Supply : USB COM from 300Watt desktop power supply. ~ 1.5A current output.  
Much appreciation to @Juraj.  Juraj

user57356: It worked when the IP was in the range because there are no valid IP addresses outside the range. 
WW.XX.YY.0 and WW.XX.YY.255 are reserved. The router is using the .1 and .2 addresses. That leaves 3-254 available, which as we see are the addresses within the DHCP range. 
You can assign a static IP address within the DHCP range, but you run the risk of disabling 1 or 2 devices. DHCP doesn’t know you’ve used one of it's addresses, so can assign it to another device. Boom! Two devices with the same address and both will not function. 
The correct way to resolve this is to log into the router and change the DHCP range. For example, increase the lower limit of 3 to (random pick) 20. Now, DHCP won’t be disturbed and will happily give out addresses to your devices. But if you need a static IP address, you’ve defined a pool, from WW.XX.YY.3 to WW.XX.YY.19

56610: <p>I have a <a href="https://wiki.keyestudio.com/KS0367_keyestudio_ESP8266_WiFi_Board" rel="nofollow noreferrer">Keyes Espressif ESP8266</a> NodeMCU, I have two LEDs that I want to control which are connected to the ESP. When I open the webpage <code>http://10.0.0.5/5</code> after uploading the sketch it works fine. If I don't open and close the website before ~ 02:30[mm:ss] the server becomes unreachable even if I close the existing connection and open a new connection in a new tab the same error yields: <code>ERR_CONNECTION_TIMED_OUT</code>  </p>

<p>If I don't open a web page before ~ 02:30[mm:ss] I also receive error <code>ERR_CONNECTION_TIMED_OUT</code></p>

<p>The web server is only made available when I hard reset the board then the same rules apply as above. </p>

<pre><code>ESP.getFullVersion() outputs: 
SDK:2.2.1(cfd48f3)/Core:2.5.1=20501000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1-7-g82abda3/BearSSL:a143020
</code></pre>

<p>Question: </p>

<p>How can I make the web server accessible constantly? </p>

<p>With the help of @Juraj I tried changing to SDK V3 which made no difference I also tried: </p>

<ul>
<li>All lwip variants</li>
</ul>

<p>My Code: 
</p>

<pre class="lang-cpp prettyprint-override"><code>// Load Wi-Fi library
#include &lt;ESP8266WiFi.h&gt;

// Replace with your network credentials
const char* ssid     = "DO_231455";
const char* password = "0828842107";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
String output5State = "off";
String output4State = "off";

// Assign output variables to GPIO pins
const int output5 = 16;
const int output4 = 4;

void setup() {
  Serial.begin(115200);

  // Initialize the output variables as outputs
  pinMode(output5, OUTPUT);
  pinMode(output4, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output5, LOW);
  digitalWrite(output4, LOW);

  Serial.print(ESP.getFullVersion());
  //WiFi.disconnect() ;
  //WiFi.persistent(false);
  //WiFi.setSleepMode(WIFI_NONE_SLEEP);
  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients
  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // turns the GPIOs on and off
            if (header.indexOf("GET /5/on") &gt;= 0) {
              Serial.println("GPIO 5 on");
              output5State = "on";
              digitalWrite(output5, HIGH);
            } else if (header.indexOf("GET /5/off") &gt;= 0) {
              Serial.println("GPIO 5 off");
              output5State = "off";
              digitalWrite(output5, LOW);
            } else if (header.indexOf("GET /4/on") &gt;= 0) {
              Serial.println("GPIO 4 on");
              output4State = "on";
              digitalWrite(output4, HIGH);
            } else if (header.indexOf("GET /4/off") &gt;= 0) {
              Serial.println("GPIO 4 off");
              output4State = "off";
              digitalWrite(output4, LOW);
            }

            // Display the HTML web page
            client.println("&lt;!DOCTYPE html&gt;&lt;html&gt;");
            client.println("&lt;head&gt;&lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"&gt;");
            client.println("&lt;link rel=\"icon\" href=\"data:,\"&gt;");
            // CSS to style the on/off buttons 
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("&lt;style&gt;html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #77878A;}&lt;/style&gt;&lt;/head&gt;");

            // Web Page Heading
            client.println("&lt;body&gt;&lt;h1&gt;ESP8266 Web Server&lt;/h1&gt;");

            // Display current state, and ON/OFF buttons for GPIO 5  
            client.println("&lt;p&gt;GPIO 5 - State " + output5State + "&lt;/p&gt;");
            // If the output5State is off, it displays the ON button       
            if (output5State=="off") {
              client.println("&lt;p&gt;&lt;a href=\"/5/on\"&gt;&lt;button class=\"button\"&gt;ON&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;");
            } else {
              client.println("&lt;p&gt;&lt;a href=\"/5/off\"&gt;&lt;button class=\"button button2\"&gt;OFF&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;");
            } 

            // Display current state, and ON/OFF buttons for GPIO 4  
            client.println("&lt;p&gt;GPIO 4 - State " + output4State + "&lt;/p&gt;");
            // If the output4State is off, it displays the ON button       
            if (output4State=="off") {
              client.println("&lt;p&gt;&lt;a href=\"/4/on\"&gt;&lt;button class=\"button\"&gt;ON&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;");
            } else {
              client.println("&lt;p&gt;&lt;a href=\"/4/off\"&gt;&lt;button class=\"button button2\"&gt;OFF&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;");
            }
            client.println("&lt;/body&gt;&lt;/html&gt;");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}
</code></pre>

<p>Worth noting (while debugging):<br>
The new client disconnects.</p>

<p><a href="https://i.stack.imgur.com/VTXEh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VTXEh.png" alt="enter image description here"></a></p>
 56610: <p><strong>The short answer: Config a static IP!</strong></p>

<p>After looking at Git Issue <a href="https://github.com/esp8266/Arduino/issues/2371" rel="nofollow noreferrer">#2371</a> I found out that I need to create a static IP address to fix this issue. I can do this by inserting <code>WiFi.config(ip, gateway, subnet)</code> just before <code>WiFi.mode(WIFI_STA)</code> in the code above. </p>

<ul>
<li>First I found the information <code>gateway</code> &amp; <code>subnet</code> I needed by opening the command prompt on a computer that's connected to the access point(router) as the one connected to the ESP8266 which functions in station mode. I did this on Windows by searching <code>Command Prompt</code> then typing <code>ipconfig</code> to obtain the following information: </li>
</ul>

<p><a href="https://i.stack.imgur.com/2iNxr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/2iNxr.png" alt="enter image description here"></a></p>

<p><strong>Replace the points with commas!</strong> See <a href="https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-class.html#config" rel="nofollow noreferrer">this</a> references for more information regarding other parameters and DNS.</p>

<hr>

<ul>
<li><p>To create an IP address you need to see your IP address in the red square in the picture above taken from the command prompt. The first three octects (numbers) of your router IP (probably <code>10.0.0.x</code>, <code>192.168.0.x</code>, or <code>192.168.1.x</code>) must match your chosen static IP. For my example the numbers to match would be <code>10.0.0</code>.</p></li>
<li><p>Next, I needed to obtain the DCHP range for my router. My router is a <a href="https://www.downloads.netgear.com/files/GDC/DG834GV5/DG834Gv5_UM_11Mar10.pdf" rel="nofollow noreferrer">Netgear Wireless ADSL2+ Modem Router DG834Gv5</a>. To obtain the range I needed to access my router settings. To access this I looked for an HTTP link under the router. For my router it was <code>http://10.0.0.2</code> along with the username and password which was <code>admin</code>, <code>admin</code> respectively. This is what it looks like: </p></li>
</ul>

<p><a href="https://i.stack.imgur.com/9EU2Q.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9EU2Q.png" alt="enter image description here"></a></p>

<p>This will vary according to your router - Then I went into Advanced settings and saw the DHCP range. <strong>This is an error on my part noted by @djsfantasi. Please see his answer regarding DHCP range selection.</strong><strike>The new static IP needs to be within the DHCP range According to one of the comments <code>brendanmatkin</code> made in Git Issue <a href="https://github.com/esp8266/Arduino/issues/2371" rel="nofollow noreferrer">#2371</a> the last number of my static IP (which is <code>ZZ</code> in <code>WW.XX.YY.ZZ</code>) needs to be <strong>outside</strong> of this range. For me it didn't work, it worked when I used a value <strong>inside</strong> this range but <code>brendanmatkin</code> knows much more than me, I'm just a novice. There might be implications that I am not aware of so I think it's worth looking into.</strike> A DHCP range looks like this below: </p>

<p><a href="https://i.stack.imgur.com/r5l3W.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/r5l3W.png" alt="enter image description here"></a></p>

<p>My inserted code looks like this below:</p>

<pre><code>void setup(void) {
  .
  .
  .
  Serial.begin(115200);
  //WiFi.disconnect();  //Prevent connecting to wifi based on previous configuration
  IPAddress ip(10,0,0,15); // this 3 lines for a fix IP-address
  IPAddress gateway(10,0,0,2); 
  IPAddress subnet(255,255,255,0);
  //WiFi.hostname("ESP8266");      // DHCP Hostname (useful for finding device for static lease)
  WiFi.config(ip, gateway, subnet);
  //Station mode:
  WiFi.mode(WIFI_STA); 
  .
  .
  .
}
</code></pre>

<p>Please comment for more info :)</p>

<p><strong>Additional information and changes I've made to IDE:</strong> </p>

<p>OS : Windows 8.1 </p>

<p>IDE : Arduino IDE V1.9.8</p>

<p>Board : <a href="https://wiki.keyestudio.com/KS0367_keyestudio_ESP8266_WiFi_Board" rel="nofollow noreferrer">Keyes ESP8266</a></p>

<p>Arduino IDE > Tools >Board (in boards manager) : Generic ESP8266 Board   </p>

<p>Arduino IDE > Tools >lwip : V2 Low Memory</p>

<p>Arduino IDE > Tools >Esp FW:"nonos.." : nonos-sdk pr-3(known issues)*</p>

<p>Power Supply : USB COM from 300Watt desktop power supply. ~ 1.5A current output.  </p>

<p>Much appreciation to @Juraj.  Juraj</p>
 57356: <p>It worked when the IP was in the range because there are no valid IP addresses outside the range. </p>

<p>WW.XX.YY.0 and WW.XX.YY.255 are reserved. The router is using the .1 and .2 addresses. That leaves 3-254 available, which as we see are the addresses within the DHCP range. </p>

<p>You can assign a static IP address within the DHCP range, but you run the risk of disabling 1 or 2 devices. DHCP doesn’t know you’ve used one of it's addresses, so can assign it to another device. Boom! Two devices with the same address and both will not function. </p>

<p>The correct way to resolve this is to log into the router and change the DHCP range. For example, increase the lower limit of 3 to (random pick) 20. Now, DHCP won’t be disturbed and will happily give out addresses to your devices. But if you need a static IP address, you’ve defined a pool, from WW.XX.YY.3 to WW.XX.YY.19</p>
