Problems with port forward/accessing an ethernet server from outside the LAN network

Hello everyone,

I am trying to make a simple webserver, based on the example form the standard Ethernet library, [https://www.arduino.cc/en/Tutorial/LibraryExamples/WebServer]. When accessing the web page on my laptop or smartphone on the same LAN network, everything works as expected. Then, I tried to make a port forward in my router, so I can access the webserver from devices outside my LAN network at home; using my WAN ip adress:port numer to connect to it. I can't get it to work, could someone help me?

I am using an Ethernet shield on an Arduino MEGA 2560. The Ethernet shield has an Wiznet W5100 chip on it and doesn't come with an MAC-address on the back.

I tried both ports 80 and 6476 for the port forward, neither does work. My internet service provender said that they do not block any of the ports.

I have used the following code:

/*
  Web Server

  A simple web server that shows the value of the analog input pins.
  using an Arduino Wiznet Ethernet shield.

  Circuit:
   Ethernet shield attached to pins 10, 11, 12, 13
   Analog inputs attached to pins A0 through A5 (optional)

  created 18 Dec 2009
  by David A. Mellis
  modified 9 Apr 2012
  by Tom Igoe
  modified 02 Sept 2015
  by Arturo Guadalupi

*/

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
// IPAddress ip(192, 168, 1, 177);
IPAddress ip(192, 168, 18, 9);
IPAddress gateway (192, 168, 18, 1);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
//EthernetServer server(80);
EthernetServer server(6476);

int SPIpinSS = 53;
int SDcardPinSS = 4;

void setup() {
  // Set pins 53 and 4 to OUTPUT mode and make them HIGH.
  pinMode(SPIpinSS, OUTPUT);
  pinMode(SDcardPinSS, OUTPUT);
  digitalWrite(SPIpinSS, HIGH);
  digitalWrite(SDcardPinSS, HIGH);

  // You can use Ethernet.init(pin) to configure the CS pin
  Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.print(", which is ");
            client.print(sensorReading * (5.0 / 1023.0) );
            client.println(" V.<br />");
            client.println("<br />");
          }
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

I have created an static LAN IP-address for the Arduino Shield, set to the same IP-address as used in the sketch, so I am sure the IP-address can't be given to another device.


I hope someone can help me.

Just confirming that you can connect fine when on the local network?

Most routers I've port forwarded on, you have to specify the external port numbers to map... do you need to fill these?

image

1 Like

Yes, connecting trough the local/LAN network works fine.

I have two other port forwards, which I use to host some multiplayer game servers on my laptop. For those i did't fill in the external ports and they work fine. I tried filling them in, but that didn't help, I am still getting an error (I forgot to write them down in my first post, oops...), err_connection_timed_out or, in my web browser.

Hmm.. ok. Your router must map using the target port numbers I guess.

Just to eliminate your ISP, have you tried using different external ports? Say port 80... and see if that makes any difference.

try to set your External port number number also.

for usual I would keep the real port for HTTP on 80 (meaning compiled in the sketch and as "internal port" in the rooter) and use another external high port from external.
e.g. 8000 external and 80 internal

1 Like

If you open access from the Internet, you better have at least password protection! I have ~ one hack tentative per week.

I have tried port 80 and later port 6476. I will try using different internal/external ports, but I am not sure how to configure that. Do I need to use the 'External port number' or 'External source port number' to do that? I don't know the difference.

Thanks for the warning, I have changed the password on the router from the factory default to something else.

Afther some experimenting, I got things working. Apparently it only works when I activate only the TPC protocol. Both TCP and UDP protocols active seems to have caused the problem (although I don't understand why, but it works). Thanks for the help!

Each end of an IP connection has an address and a port number. I think "External port number" is the port your browser connects to, while "External source port number" is the port your browser connects from. I think you want to open the "External source port number" to all ports. I don't know if that means leaving them blank or putting in 0-65535. If what you have now (0-0) means only connections from port 0 are allowed then that would explain why you can't get a connection from outside.

1 Like

It works now. Thanks everyone!

I set both the internal and external port to 80. I left the external source port blank. I set the protocol to TCP only.
I have an EchoLife EG8245Q router, made by Huawei.

1 Like