Web site now serving web page

This code works perfectly except….. It ran for over an hour and a half. Then I shut everything down and came back about an hour later and nothing. The server is running (I can see and connect to the ssid). The server dhcp is handing out IP addresses just fine. But when I try to connect to the server through a web browser I get nothing, failure to connect.

/*
  ESP32 WiFi AP Mode
  http:://www.electronicwings.com
  Adapted Mar 16, 2026 for specific project
  Modified by: John Wright
*/

#include <WiFi.h>

const char* ssid = "Composter";   /*Set Your SSID*/
const char* password = "westviewHS";   /*Set Your Password*/

WiFiServer server(80); /* Instance of WiFiServer with port number 80 */
WiFiClient client;

IPAddress Ip(192, 168, 4, 1);
IPAddress NMask(255, 255, 255, 0);

String request;
#define  LED 7
int LED_Status; 

void setup(){
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  Serial.println("ESP32 Access Point Mode");
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid, password);
  delay(100);
  WiFi.softAPConfig(Ip, Ip, NMask);
  Serial.print("Connect to IP address: ");
  Serial.println(WiFi.softAPIP());
  server.begin();
}

void html (){
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("Connection: close");
  client.println();

  client.println("<!DOCTYPE HTML>");
  client.println("<html>");

  client.println("<head>");
    client.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
    client.println("<link rel=\"icon\" href=\"data:,\">");
    client.println("<style>");
      client.println("html { font-family: Roboto; display: inline-block; margin: 0px auto; text-align: center;}");
      client.println(".button {background-color: #4CAF50; border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer;");
      client.println("text-decoration: none; font-size: 25px; margin: 2px; cursor: pointer;}");
      client.println(".button_ON {background-color: white; color: black; border: 2px solid #4CAF50;}");
      client.println(".button_OFF {background-color: white; color: black; border: 2px solid #f44336;}");
    client.println("</style>");
  client.println("</head>");
  client.println("<body>");
  client.println("<h2>Composter Motor Controller</h2>");
  client.println("<p>Click to start/stop rotating the Composter</p>");

  if(LED_Status == LOW) 
  {
    client.print("<p><a href=\"/LED_ON\n\"><button class=\"button button_ON\">ON</button></a></p>"); 
  } 
 
  else
  {
    client.print("<p><a href=\"/LED_OFF\n\"><button class=\"button button_OFF\">OFF</button></a></p>"); 
  } 
 
  client.println("</body>");
 client.println("</html>");     
}

void loop()
{
  client = server.available();
  if(!client)
  {
    return;
  }

  while (client.connected())
  {
    if (client.available())
    {
      char c = client.read();
      request += c;

      if (c == '\n')
      {
        if (request.indexOf("GET /LED_ON") != -1) 
        {
          Serial.println("Motor Rotating");
          digitalWrite(LED, HIGH);
          LED_Status = HIGH;
        }

        if (request.indexOf("GET /LED_OFF") != -1)
        {
          Serial.println("Motor Stopped");
          digitalWrite(LED, LOW);
          LED_Status = LOW;
        }
        html();
        break;
    }
    }
  }

  delay(1);
  request="";
  client.stop();
}

There is one error that shows up after the code is running, it shows up in the bottom window:

JmDNS(fe80-0-0-0-a34a-6ca0-cf83-1f9b-wlp2s0.local.).Timer] WARN javax.jmdns.impl.tasks.resolver.DNSResolverTask - ServiceResolver(fe80-0-0-0-a34a-6ca0-cf83-1f9b-wlp2s0.local.).run() exception 
java.net.SocketException: Operation not permitted
	at java.base/sun.nio.ch.DatagramChannelImpl.send0(Native Method)
	at java.base/sun.nio.ch.DatagramChannelImpl.sendFromNativeBuffer(DatagramChannelImpl.java:1005)
	at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:966)
	at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:889)
	at java.base/sun.nio.ch.DatagramChannelImpl.blockingSend(DatagramChannelImpl.java:952)
	at java.base/sun.nio.ch.DatagramSocketAdaptor.send(DatagramSocketAdaptor.java:193)
	at java.base/java.net.DatagramSocket.send(DatagramSocket.java:662)
	at javax.jmdns.impl.JmDNSImpl.send(JmDNSImpl.java:1634)
	at javax.jmdns.impl.tasks.resolver.DNSResolverTask.run(DNSResolverTask.java:73)
	at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
	at java.base/java.util.TimerThread.run(Timer.java:516)
[fe80-0-0-0-a34a-6ca0-cf83-1f9b-wlp2s0.local..recover()] WARN javax.jmdns.impl.JmDNSImpl - RECOVERING
[JmDNS(fe80-0-0-0-a34a-6ca0-cf83-1f9b-wlp2s0.local.).State.Timer] WARN javax.jmdns.impl.tasks.state.DNSStateTask - Canceler(fe80-0-0-0-a34a-6ca0-cf83-1f9b-wlp2s0.local.).run() exception 
java.net.SocketException: Operation not permitted
	at java.base/sun.nio.ch.DatagramChannelImpl.send0(Native Method)
	at java.base/sun.nio.ch.DatagramChannelImpl.sendFromNativeBuffer(DatagramChannelImpl.java:1005)
	at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:966)
	at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:889)
	at java.base/sun.nio.ch.DatagramChannelImpl.blockingSend(DatagramChannelImpl.java:952)
	at java.base/sun.nio.ch.DatagramSocketAdaptor.send(DatagramSocketAdaptor.java:193)
	at java.base/java.net.DatagramSocket.send(DatagramSocket.java:662)
	at javax.jmdns.impl.JmDNSImpl.send(JmDNSImpl.java:1634)
	at javax.jmdns.impl.tasks.state.DNSStateTask.run(DNSStateTask.java:131)
	at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
	at java.base/java.util.TimerThread.run(Timer.java:516)
[fe80-0-0-0-a34a-6ca0-cf83-1f9b-wlp2s0.local..recover()] WARN javax.jmdns.impl.DNSStatefulObject$DefaultImplementation - Wait for canceled timed out: DNS: fe80-0-0-0-a34a-6ca0-cf83-1f9b-wlp2s0.local. [fe80:0:0:0:a34a:6ca0:cf83:1f9b%wlp2s0/fe80:0:0:0:a34a:6ca0:cf83:1f9b%wlp2s0] state: canceling 1 task: null
[fe80-0-0-0-a34a-6ca0-cf83-1f9b-wlp2s0.local..recover()] WARN javax.jmdns.impl.JmDNSImpl - fe80-0-0-0-a34a-6ca0-cf83-1f9b-wlp2s0.local..recover() Could not recover we are Down!
[JmDNS(192-168-4-2.local.).Timer] WARN javax.jmdns.impl.tasks.resolver.DNSResolverTask - ServiceResolver(192-168-4-2.local.).run() exception 
java.net.SocketException: Operation not permitted
	at java.base/sun.nio.ch.DatagramChannelImpl.send0(Native Method)
	at java.base/sun.nio.ch.DatagramChannelImpl.sendFromNativeBuffer(DatagramChannelImpl.java:1005)
	at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:966)
	at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:889)
	at java.base/sun.nio.ch.DatagramChannelImpl.blockingSend(DatagramChannelImpl.java:952)
	at java.base/sun.nio.ch.DatagramSocketAdaptor.send(DatagramSocketAdaptor.java:193)
	at java.base/java.net.DatagramSocket.send(DatagramSocket.java:662)
	at javax.jmdns.impl.JmDNSImpl.send(JmDNSImpl.java:1634)
	at javax.jmdns.impl.tasks.resolver.DNSResolverTask.run(DNSResolverTask.java:73)
	at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
	at java.base/java.util.TimerThread.run(Timer.java:516)
[192-168-4-2.local..recover()] WARN javax.jmdns.impl.JmDNSImpl - RECOVERING
[JmDNS(192-168-4-2.local.).State.Timer] WARN javax.jmdns.impl.tasks.state.DNSStateTask - Canceler(192-168-4-2.local.).run() exception 
java.net.SocketException: Operation not permitted
	at

This keep repeating. I have no idea what this is trying to tell me. Any help appreciated.

I am totally ignorant about HTML, etc., and not very strong in networking, but I do know that 192.168.4.1 is a reserved address, so just change it to something like 192.168.100.23

1 Like

192.168.4.1 is within the private address range defined by RFC 1918, so it is reserved for private networks, but it is not a special or fixed address. It can be (and is) used as a default gateway address by some devices. That’s fine.


@ov10fac

Which ESP32 board or module are you using, and is it a standard development board or a custom setup? (GPIO 7 ?)

The logs show repeated JmDNS Operation not permitted warnings, which probably occur because the PC tries to send multicast DNS packets to discover or advertise .local hostnames on the ESP32 AP interface but lacks permission (just being blocked by the OS or firewall.); I think these warnings can be ignored as they don’t affect the ESP32 AP or web server.

The apparent hang is probably because the ESP32 code handles only one client at a time; a stalled or slow client can block the loop, and the PC’s failing mDNS may delay the browser.

You could try to add client timeouts to free pending clients quickly and not jus rely on receiving ‘\n'

Hi,
I can offer you an alternative consisting of a project similar to yours which you can run as a baseline to see if the issue replicates in this case as well. This will help you know if the issue is with your code or maybe something else..

Go to https://mongoose.ws/wizard/#/output?board=arduino-esp32&ide=Arduino&rtos=baremetal, select 'Settings' panel and choose a destination directory, then download the project to your computer by clicking the blue 'Generate C/C++ code' button on the upper right corner of the page. Then, open it with the Arduino IDE, edit the Wi-Fi credentials in the wizard.ino file, build it, and flash it on your ESP32. You should see the logs indicating successful connection, including the assigned IP address.

This project is based on the Mongoose Networking Library, a networking library for embedded devices and a lightweight solution for this kind of application.

One more thing: I see in your code that you are generating the UI by printing HTML line by line. The Mongoose Wizard tool that creates this project allows you to build your UI visually without writing any frontend code. It should make development a lot easier for you. Both Mongoose Library and the Wizard tool are well documented, in case you are interested in learning more about using them and building web interfaces without writing any code at all.

Heads up: I am part of the Mongoose development team. Hope this helps you with your issues.

This is very confusing. The reason I said what I said in post 2 is that if I ask Google if it's special, this is the response.

Yes, 192.168.4.1 is a special private IP address primarily used as a default gateway/admin login for routers and networking devices. It is commonly used by brands like D-Link, TP-Link, Linksys, and Netgear, as well as for ESP8266/ESP32 development boards in Access Point mode.

[image]Arduino Forum +1

  • Private Address: It is a non-routable, private IP (class C) intended for local area networks (LAN) only, meaning it cannot be accessed directly from the public internet.
  • Router Access: Entering http://192.168.4.1 into a browser allows users to access the router's settings, configure Wi-Fi, and change security options.
  • Why It's Used: It is often chosen for IoT or smart devices to avoid conflicts with common, pre-existing local network IPs like 192.168.0.1 or 192.168.1.1.

[image]Arduino Forum +4

If you are having trouble connecting, it is likely the default IP for your specific network, and you can confirm this by looking for the "default gateway" address in your network settings.

My ISP gives us EERO routers; I have 2. I no longer have direct access to the router like I used to with TP-Link, etc. They give us an app. The app says 192.168.4.1 is my gateway, but if I try to use it, I get


Many sketches will not work because the address 192.168.4.1 is hard-coded somewhere, and all I get is that screen. Some do work, which is ultra confusing. I have looked for a way to change it, but so far, I haven't had any luck.
Because I turn 84 next week and am a bit autistic, I often misremember or confuse things, so I decided to try a simple 8266-type AP sketch just now. I started to look at the headers and quickly fell into a rabbit hole. I might find them all (it's simple, after a verify, just highlight the include and click), but from the first hdr I am already 4 deep, and the last 3 had more hdrs, so I am giving up on that approach.
I am 100% sure I have asked the following question in the forum before and received no answer, so while I have your attention and you seem to know the subject matter,

How can I change the gateway from a sketch, and if I have a board/device with existing AP code and standard 192.168.4.1 how do I connect without turning off my router?

Your reply was of interest to me but when I clicked the link I got this

I am flagging you so the mods can check it out

Since OP is using AP mode, you first connect to it using SSID and Password. Since you're not connecting to the router / gateway at all, its IP address is irrelevant.

That's kind of the role that's being taken by the ESP here ➜ the ESP32 creates its own Wi-Fi network in access point mode and acts as a local server. Its IP address is set to 192.168.4.1 via WiFi.softAPConfig, and this same address is also advertised to connected clients as the gateway.

Clients receive an address in the 192.168.4.x range and communicate directly with the ESP32 at 192.168.4.1.

There is no routing to another network or Internet access, so the “gateway” role is limited to being the central node of this isolated local network.

AH, so the first level of 'address' is the SSSID? like 100 Someplace Circle and the 192.168.4.1 is like apartment 123?

I have several devices that I connect to in what I call weird ways. I can't remember details, but the high-level concept is I turn the device on, go to my phone WiFi settings and tap the special SSID it told me about. Now I go back to the App and connect it.

Does this mean my phone is now only connected to the app and I have lost the phone to router/internet connection, or is my phone aboe to connect to two things at once?

This explains what I thought of as sometimes 192.168.4.1 works and sometimes it doesn't. Is this connected to a softAP versus just an AP? The reason I ask is I went looking for some sample 8266 code after I posted earlier and saw the line

 IPAddress myIP = WiFi.softAPIP();

I will try that later to see what it prints. My bet is that is not 192.168.4.1 I just noticed the line previous

WiFi.softAP(ssid, password);

The one time a comment would help, it isn't there.

Does anyone know of a big picture book on WiFi?

That analogy is incorrect.

The SSID is not an address at all. It is only a network name, essentially a label that devices use to identify and select a Wi-Fi network. It operates at the Wi-Fi layer and has no role in IP routing or addressing.

If you want an analogy, may be think of the SSID as the name of a city you choose to move into. It identifies the place but does not tell you how to reach anything inside the city.

When you enter the city and register with the local administration, you are assigned a phone number. That number is your IP address, for example 192.168.4.2. Other residents can use it to reach you.

The ESP32 is the local administration. It is both the city hall and the central telephone exchange. Its own number is 192.168.4.1. That is the number you call when you want to talk to it.

Because it is also the central telephone exchange/central switchboard of the city, all communications go through it.

In this setup there is no phone connection to other cities, so it mainly assigns numbers and handles all calls within this single isolated city. There is no routing.

To “call other cities” in this analogy, the ESP32 would need a connection to an external network, like the Internet or another LAN. In technical terms, this means it would need a second interface connected to that network (for example Wi-Fi in station mode or Ethernet) and proper routing or NAT configured.

It would have to forward traffic from its local network (192.168.4.x) to the external network, translating local addresses into an external address and vice versa.

➜ In the analogy, the city hall (ESP32) would act as a full telephone exchange capable of connecting local phone numbers to numbers in other cities. Without that, all communications remain inside the city; residents can only call each other or the city hall itself.

Looks to me that malwarebytes does not like the domain name. We never noticed that… Mods should confirm it’s OK. Thanks for reporting the issue!

sonofcy, you are correct if I was publishing to the internet. But I am behind a firewall that uses NAT so technically I can use just about any addressing scheme that fits the condition. Thanks for you comments.

AH, that is a better analogy. I should really know better because I live very close to the last local phone network to join the Bell network. They had to use an operator to get connected outside of their small area. The operator connected the two networks with a patch panel. I guess that is equivalent to routing between two different interfaces/networks.

In a further strange world, where I live was the last T-Bar system.

1 Like

sonofcy,

I will definately try that. Thank you.

WHAT? Correct about what, I am the noob here when it comes to networking.

Try what?

Using the city/phone exchange analogy helps a lot, thank you.

I have a related question, I have had close to a dozen routers over the years and never heard of 192.168.4.1. The address to configure the router was always something like 192.168.0.1 or 192.168.0.0 or 100.0 and similar schemes. When did 192.168.4.1 become the 'standard'?

I want to thank everyone. I learned a lot from the conversations. The address 192.168.4.1 should be ok from an internet standpoint since my local network is completely different so it never connects to that and can never get to the internet. That’s why I went with softAP to make a small stand alone network without access to the internet. But I never considered the possibility that my browser might have an issue with it. I will test that later today. In the mean time I can change the ip to a “private” address that doesn’t interfere with my own network.
But after all is said and done, the big question is why did it work for an hour or so then just stop? That tells me the code is OK so must be something on the network or in my browser. I have tried on two different PCs and two different browsers with the same result.
I am using SEEED ESP32C3 boards. I went that rout mainly because of the footprint size. These (there will be two) systems will control a motorized compost tumbler. The code in question will be part of the system that turns the motor on and off to rotate the tumbler. The second will be inside the barrel and read temp and moisture. The problem on that one is protection from the elements, but that’s a different issue for another time.

Again, thanks for all your comments and I will for sure change that ip address just to eliminate it from my list of possible causes.

No major vendor that I know of ships devices with 192.168.4.1 as the default but it's a possibility.

And it can always be configured. I have my pfSense router supporting three subnets:
192.168.10.1 / 24
192.168.20.1 / 24
192.168.25.1 / 24