How can I translate my public ip address to my server address

I have a simple sketch that

  1. Starts a web server
  2. Requests the arduino public IP from ipify

The web server ip address on my local network is 192.168.0.105
When I enter that into a web browser I can see the html page.

My public ip address is xx.xxx.xxx.xxx
I can ping that address no problem and get response
But when I enter it into a web browser I dont see the html page. I get a connection refused error.

How can I use the public ip address to access my web server?

#include "arduino_secrets.h"
#include <ArduinoHttpClient.h>
//#include <WiFi101.h>    // use this for MKR1000
#include <WiFiNINA.h>     // use this for MKR1010 or Nano 33 IoT

//#include <Arduino_JSON.h>
// server address:
const char serverAddress[] = "api.ipify.org";
int port = 80;
int ledPin = 2;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int keyIndex = 0;                 // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;      //connection status
WiFiServer server(80); 
//WiFiClient serverClient = server.available();
// request timestamp in ms:
long lastRequest = 0;
// interval between requests:
int interval = 10000;
int gotResponse = 0;
String publicIp;

void setup() {
  Serial.begin(9600);
  while (!Serial);
  while ( WiFi.status() != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(SECRET_SSID);     // print the network name (SSID);

    // Connect to WPA/WPA2 network:
    WiFi.begin(SECRET_SSID, SECRET_PASS);
  }
  server.begin();
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void loop() {
  wifi = server.available();

  if (wifi) {
    printWEB();
  }
  getPublicIP();
}
void printWEB() {

  if (wifi) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (wifi.connected()) {            // loop while the client's connected
      if (wifi.available()) {             // if there's bytes to read from the client,
        char c = wifi.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        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:
            wifi.println("HTTP/1.1 200 OK");
            wifi.println("Content-type:text/html");
            wifi.println();
           
            //create the buttons
            wifi.print("Click <a href=\"/H\">here</a> turn the LED on<br>");
            wifi.print("Click <a href=\"/L\">here</a> turn the LED off<br><br>");
            
            int randomReading = analogRead(A1);
            wifi.print("Random reading from analog pin: ");
            wifi.print(randomReading);
           
            
            

            // The HTTP response ends with another blank line:
            wifi.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
        }

        if (currentLine.endsWith("GET /H")) {
        digitalWrite(ledPin, HIGH);     
         Serial.println("GOT GET Request"); 
        }
        if (currentLine.endsWith("GET /L")) {
        digitalWrite(ledPin, LOW);   
         Serial.println("GOT GET Request"); 
        }

      }
    }
    // close the connection:
    wifi.stop();
    Serial.println("client disconnected");
  }
}
/*void getPublicIP() {
  WiFiClient client = server.available();
  if (millis() - lastRequest > interval ) {
  // This will send the request to the server
  client.print(String("GET ") + "/" + " HTTP/1.1\r\n" +
               "Host: " + serverAddress + "\r\n" + 
               "Connection: close\r\n\r\n");
  Serial.println("Respond:");
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  
  Serial.println();
  Serial.println("closing connection");
  }
  lastRequest = millis();

}*/
void getPublicIP() {
  if (gotResponse == 1) {
    return;
  }
 if (millis() - lastRequest > interval ) {
    // assemble the path for the GET message:
    String path = "/";

    // send the GET request
    Serial.println("making GET request");
    client.get(path);

    // read the status code and body of the response
    int statusCode = client.responseStatusCode();
    String response = client.responseBody();
    Serial.print("Status code: ");
    Serial.println(statusCode); // status code
    if (statusCode == 200) {
      gotResponse = 1;
      publicIp = response;

    }
    Serial.print("Response: ");
    Serial.println(publicIp);
    lastRequest = millis();
  }
}

You need to setup port forwarding in your router and direct that specific traffic to your private IP address.

1 Like

I have used DuckDNS for that.

Thanks for the reply.
Could you explain at a high level what your process was please?

start a web server on a mega with Ethernet shield

expose it to the Internet with port forwarding

create a URL in duckDNS

pass the exposed address to DuckDNS

1 Like

I'm looking into Duck DNS and found this library that looks promising.

When I import it into my sketch for my Arudino Uno WIFI Rev2 I get the following error

fatal error: stdlib_noniso.h: No such file or directory
 #include "stdlib_noniso.h"

Any ideas?

You don't need any library for this job. The IP visibility has nothing at all to do with the code running on the Arduino.

Looking at your posts again, it looks like "ipify" performs the same task as DuckDNS, your problem is only to configure your router for pass-through.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.