SUCCESS with Port Forwarding

Examples/Ethernet/WebClient work fine on my local Private LAN & any connected PC or wireless device can access the web page on 192.168.1.177 as intended.

I'm wanting to access this Arduino Web Server from an outside Public IP address.

My ISP only provides me with a dynamic IP address so I've successfully been able to use either / both noip.com and Duck DNS to give me something akin to a static address. Using either of those addresses I can access the Modem/Router login page BUT get no further.

I have no problems navigating down to the router Advance Config pages but my problem is what should I use as the Service Port number ?

Google searches etc suggest that various remote devices like say an IP Camera or even games have pre specified Port numbers but nothing is identified for Arduino.

I've tried the common port numbers like 8080 but just won't trigger the port forwarding.

My original attempts to set up port forwarding were using a NetComm NB6Plus but I gave up on that & purchased a TP_Link TD-W8960N but without any success.

My ISP (iPrimus) confirms that they don't block any ports including 80.
I've been right through http://portforward.com/ and that did not help.

I'm using sites like http://www.t1shopper.com/tools/ to scan the ports but none are shown open.

I'm expecting to be able to use a public address like 203.142.147.198:8080 and get through to the Arduino.

Any comments / assistance would be appreciated on what seems to be a frequent posting problem

Regards

I tried loads of ports on mine, including :8080, and eventually gave up.

Then I said bugger this, must be one that works, tried a few more and :8085 worked....

Thanks for that link to t1shoper btw, very informative and handy.

My server is currently running here.

Just struck me. You didn't post your code, but do you have a line like this to set the port in the sketch:

EthernetServer server(8085); //server port

JimboZA I've been waiting for guru SurferTim to respond to my "plea for help" but you may have hit the nail on the head. Something like the code you suggest "EthernetServer server(8085); //server port" has always been missing from what I've seen of the examples.

No, so far I've just followed the examples which excludes that line of code, I'll give it a try.

By the way your link "http://jimboza.gotdns.com:8085/" worked for me from here in Australia

Thanks in anticipation

I think the examples usually have the line, but probably with (80), like this one. It’s the only way, afaik, that the server knows which port to use. Forwarding the port on the router will have no practical effect if there’s no server there.

FWIW, here’s my code. Both SurferTim and zoomkat were big help to me a year ago when I was figuring this stuff out.

// based on zoomkat 4-1-12

//jim 7 dec 2013 with my details- ip address etc

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


byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 
  10, 0, 0, 200}; // ip in lan
byte gateway[] = { 
  10, 0, 0, 2 }; // internet access via router
byte subnet[] = { 
  255, 255, 255, 0 }; //subnet mask
EthernetServer server(8085); //server port

String readString; 

const int chipSelect = 4;
//////////////////////

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

  // to be safe, disabling SD explicitly
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);


  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();


  Serial.println("Server page test"); // so I can keep track of what is loaded
  Serial.print("Server is at lan ip ");
  Serial.println(Ethernet.localIP());
  Serial.println(millis());
  Serial.print("Setup finished");
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 
          

          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 600");  // refresh the page automatically every 10 mins
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          //client.println("<TITLE>ArduinoMation test page</TITLE>");
          //display temp in browser tab
          client.print("<title>");
          client.print("JimboZA");
          client.println("</title>");
          //client.println("<link href=\"jimza.ico\" rel=\"icon\" type=\"image/x-icon\" />");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Testing automation via web</H1>");

          client.println("<H3>Thanks to Arduino forum guys for help</H1>");

          client.println("
"); 
          client.print("Refreshes every 10 mins, or hit browser's refresh to update millis and temp");

          client.println("
"); 
          client.println("
"); 

          client.print(millis());
          client.print(" milliseconds since reset or power up");
          client.println("
"); 
          
          client.print("Temperature ");
          client.print(analogRead(5)/2);
          client.print("C");
          client.println("
"); 
          

          client.println("<H4>Hardware:</H4>");
          //client.println("
");  
          //client.print("<a href=\"http://arduino.cc/en/Main/ArduinoBoardUnoArduino\">Arduino UNO</a>");
          client.println("Arduino UNO");
          client.println("
");
          client.println("Ethernet shield (includes SD card slot)"); 
          client.println("
");
          client.println("LM35 temerature sensor"); 



          client.println("</BODY>");
          client.println("</HTML>");

          delay(1);
          //stopping client
          client.stop();


        }
      }
    }
  }
}

Did you get it working with port 8085? If you can get the router's login page from the internet, you should be able to port forward to the private IPs like your Arduino. Some ISPs are now blocking port 80 inbound requests to dynamic IPs, but it appears your's isn't.

If you are planning on exposing your Arduino to the internet, you will need a bit more fault tolerance and security than if it is strictly on a localnet.

@JimboZA: Can I test your server code from here? I'm not a hacker, so I don't like to test stuff without the "victim" approving it and being there to reset the Arduino. I want to see if I can get it to lock up. That seems to be a common complaint recently. I have code posted on the playground that prevents this type lockup I want to test.

I've just followed the advice from JimboZA & now have WebServer working fine adding the line of code
EthernetServer server(8085);
I then went back and changed code to the original EthernetServer server(80); and that also works OK.

For others following this post in my TP-Link modem router I have set up NAT Virtual Server - which is Port Forwarding as follows:
Server Name: Arduino-8085
External Port Start: 8085
External Port End: 8085
Protocol: TCP/UDP
Internal Port Start: 8085
Internal Port End: 8085
Server IP Address: 192.168.1.177
WAN Interface: ppp0.2 (this may just relate to my ISP iprimus here in Australia
Status: Enabled

I also have a similar entry for port 80 instead of 8085 and that works fine.

Now as previously mentioned to get around my ISP providing me with just a dynamic external IP I have been using both noip.com and also duckdns.org . I notice JimboZA uses some redirection server gotdns which must be similar. e.g. http://jimboza.gotdns.com:8085

Although duckdns periodically changed my external IP address all I need to do is enter username.duckdns.org:8085/ and if finds its way to to my Arduino Server

I've noticed duckdns redirection seems to over-ride and external IP address specified bu NOIP.Com

QUESTION:
This has been a learning curve for myself & maybe others following this post with respect to Service Port numbers but does anyone know the full range of ports numbers available and is their any restriction on what can be used by Arduinos ???

Yep my ".gotdns.com" is one of the domain name styles from dyn (p.k.a dyndns).

It was one of the providers in my router's drop down list. The router keeps dyn updated on my ip addy and they keep my domain name pointed to that.

@JimboZA: Your server code failed. I locked it up. If you haven't gotten my PM, reset it now.

This fix for that is here:
http://playground.arduino.cc/Code/WebServerST
Look for the checkSockStatus() function in the new server code. It is about 3/4 down the page at the end of the first server example.

edit: I see you reset it. I can reach it again.

OK ST.... I see you call it from myStuff() which is called from loop(), so I'll just stick the call to that in loop()?

@rbright we kind of hijacked your thread, but probably a good thing for you to add too...

Thanks for letting me test your server. :slight_smile:

You can put the call in loop(). I put it in the myStuff() function because that is where I call ShowSockStatus() when checking my sockets during the debug. The ShowSockStatus() function is also very handy.

@rbright: If you are going to expose your Arduino server code to the internet, you should also include that checkSockStatus() function.

Here is how to add that function. Then call it every iteration of your loop() function.

// add these includes
#include <utility/w5100.h>
#include <utility/socket.h>

// add these arrays to your global variables
unsigned long connectTime[MAX_SOCK_NUM];
byte socketStat[MAX_SOCK_NUM];

// and this function to the end of your sketch
void checkSockStatus()
{
  unsigned long thisTime = millis();

  for (int i = 0; i < MAX_SOCK_NUM; i++) {
    uint8_t s = W5100.readSnSR(i);

    if(s == 0x17) {
      if(socketStat[i] == 0x14) {
        connectTime[i] = thisTime;
      }
      else if(socketStat[i] == 0x17) {
        if(thisTime - connectTime[i] > 30000UL) {
          Serial.print(F("\r\nSocket frozen: "));
          Serial.println(i);
          close(i);
        }
      }
    }
    else connectTime[i] = thisTime;

    socketStat[i] = W5100.readSnSR(i);
  }
}

Ok, socket fix thingy compiled and uploaded.... test away ST.

@JimboZA: I gave it my best shot. I can't lock it now. It keeps responding.

All of the above is excellent information for which I thank the contributors.

As I asked above "with respect to Service Port numbers but does anyone know the full range of ports numbers available and is there any restriction on what can be used by Arduino"

To assist others searching on Port Forwarding problems, how do we change the heading of the topic to something like "SUCCESS - Port Forwarding"

Alternatively maybe Moderator can make something like this a "sticky topic".

Regards all

Port forwarding and the number of available ports depends on the type of router and how the maker set up port forwarding. Below is a screen capture of my Netgear 614 wireless router.

rbright:
To assist others searching on Port Forwarding problems, how do we change the heading of the topic to something like "SUCCESS - Port Forwarding"

You can modify the heading yourself: just make sure you do it in the opening post not one of the replies.

Go to the post and choose More > Modify in the bottom right corner.

I wouldn't advocate this particular thread as a sticky- it's a bit haphazard, as threads are wont to be. Maybe "someone" 8) could write a "port-forwarding 101" though...

Zoomcat what I see is the specific ports you have set up on your Modem/Router but what is the theoretical highest port number e.g. could someone add a port number 9999 or higher.

To add to this question could someone add on their modem/router a Start Port of 0 and End Port of 9999. I'd expect this may be a security risk but so what if you don't have hardware connected to specified ports. I'd expect there may be some PC system devices which may be in that range.

Comments?

The below user's manual indicates the port number range for my router is from 1 to 65534.

http://documentation.netgear.com/wgr614v9/enu/202-10308-01/WGR614v9-07-08.html

@zoomkat: I don’t know if you noticed, but that is your server code I was crashing. Insure you include my fix to your server code or you may become a victim of that hack.

CatweasleNZ was the user who brought this bug to my attention. Thanks again to him.