Question about the example"An Auto-Refreshing Client Page " example

I have tried the example “An Auto-Refreshing Client Page”(GHI Electronics – Where Hardware Meets Software).

I have installed the “DHCP SERVER” before running the example. (the link of “DHCP SERVER” http://www.dhcpserver.de/dhcpsetup.htm)

After openning a web browser I can play the 3 buttons, but it lasted only about 10 seconds and the refresh stopped.

why?


Renewing DHCP lease.
DCHP - IP Address = 192.168.178.75 ... Net Mask = 255.255.255.0 ... Gateway = 192.168.178.1
listening...
Accepted a connection from 192.168.178.65:1373
listening...
Accepted a connection from 192.168.178.65:1374
listening...
Accepted a connection from 192.168.178.65:1375
listening...
Accepted a connection from 192.168.178.65:1376
listening...
Accepted a connection from 192.168.178.65:1378
listening...
Accepted a connection from 192.168.178.65:1379
listening...
Accepted a connection from 192.168.178.65:1380
listening...
Accepted a connection from 192.168.178.65:1381
listening...
Accepted a connection from 192.168.178.65:1382
listening...
Accepted a connection from 192.168.178.65:1383
listening...
Accepted a connection from 192.168.178.65:1384
listening...
Accepted a connection from 192.168.178.65:1385
listening...
Accepted a connection from 192.168.178.65:1386
listening...
Accepted a connection from 192.168.178.65:1387
listening...
Accepted a connection from 192.168.178.65:1388
listening...
Accepted a connection from 192.168.178.65:1389
listening...
Accepted a connection from 192.168.178.65:1390
listening...
Accepted a connection from 192.168.178.65:1391
listening...
Accepted a connection from 192.168.178.65:1392
listening...
Accepted a connection from 192.168.178.65:1393
listening...
Accepted a connection from 192.168.178.65:1394
listening...
Accepted a connection from 192.168.178.65:1395
listening...
Accepted a connection from 192.168.178.65:1396
listening...
Accepted a connection from 192.168.178.65:1397
listening...
Accepted a connection from 192.168.178.65:1398
listening...
Accepted a connection from 192.168.178.65:1399
listening...
Accepted a connection from 192.168.178.65:1400
listening...
Accepted a connection from 192.168.178.65:1401
listening...
Accepted a connection from 192.168.178.65:1402
listening...
Accepted a connection from 192.168.178.65:1403
listening...
Accepted a connection from 192.168.178.65:1404


Your browser has to request it, maybe it has decided to stop - Chrome has some logic built in to watch for circular redirects.

Try testing with Chrome, IE, safari - different browsers and see if results are similar.

A note on meta refresh - different security settings may ignore it. Javascript may also be used to redirect - but again, it is up to the browser whether to accept it or not.

I bet you’ve exhaused sockets on the device. What board are you using, Spider? That has a lot of memory, but still tops out in the ~90 ports used. You need tp read through the code and see if it’s closing sockets at the end of the process - the newSock.Close() is the key. Breakpoint that and see if it gets run?

if only Gadeteer.Socket implemented IDisposable, like System.net.Socket…

using (Socket s = new Socket(…))
{
}

not actually sure if it would help in this case, but generally with i/o, it’s nice to have disposable objects that clean cleans themselves up properly when disposed. are there any reasons why these classes don’t implement disposable? (i can understand not wanting finalizers, but not sure i see much disadvantage to disposable)

@ Dr9 -

I have tried “IE”, “Chrome” and “Firefox” again. I find that “Chrome” and “Firefox” have the same problem. The “Refresh” stopped in “Chrome” and “Firefox” after about 10 seconds

The “Refresh” in “IE” can keep running every 1 second at the beginning, but the “Refresh” will be More and more slowly after about 10 seconds.

Can I say that it is the problem of webbrowser?

If yes, how can I set the webbrowsers, so that the example code runs well?

@ Brett -

I have built a board on the basis of “Cobra” by myself. The layout of my board is same as “FEZ Cobra Mainboard”.

I have tried the example codes with “breakpoint” at “newSock.Close();” again. I find that the debug step stopped at " Socket newSock = listenSocket.Accept();" after about 30 times “listening”. I don’t know why.

I have tried the example codes with “IE”, “Firefox” and " Chrome". The “Refresh” in “IE” can keep running every 1 second at the beginning, but the “Refresh” will be more and more slowly after about 10 seconds. The “Refresh” stopped after about 10 seconds, if I use , “Firefox” and " Chrome".

I think I have only used the port 80, I am not very clear about “exhaused sockets on the device”.

I don’t know how can I go on. How can I solve the problem?

The example codes is as follow:


using System;
using System.Net;
using System.Text;
using System.IO;
using System.Threading;
using System.Net.Sockets;

using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.USBHost;
using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.Net.NetworkInformation;

namespace Webtest
{
    public class Program
    {
        static InputPort upButton     = new InputPort((Cpu.Pin)EMX.Pin.IO21, true, Port.ResistorMode.PullUp);

        static InputPort selectButton = new InputPort((Cpu.Pin)EMX.Pin.IO1, true, Port.ResistorMode.PullUp);

        static InputPort downButton   = new InputPort((Cpu.Pin)EMX.Pin.IO18, true, Port.ResistorMode.PullUp);

        // Read the states of the Cobra buttons and build a web page showing their states

        // Read the states of the Cobra buttons and build a web page showing their states

        static string ButtonPage(string sourceIP)
        {
            // Determine the states of the three cobra buttons

            string ubs; if (upButton.Read() == false) ubs = "Pressed"; else ubs = "Released";

            string sbs; if (selectButton.Read() == false) sbs = "Pressed"; else sbs = "Released";

            string dbs; if (downButton.Read() == false) dbs = "Pressed"; else dbs = "Released";



            // Build the web page

            string s = "<html>\n";                                      // First the page type

            s += "<head><title>Fez Cobra Test Page</title>";            // now the page header

            s += "<META http-equiv=\"REFRESH\" content=\"1;URL=" + sourceIP + "\">";    // Auto-refresh

            s += "</head>\n<body>\n";                                   // start the body        

            s += "<p>Up Button State = <i>" + ubs + "</i></p>";         // Up button, state in italics

            s += "<p>Select Button State = <i>" + sbs + "</i></p>";     // Select button, state in italics

            s += "<p>Down Button State = <i>" + dbs + "</i></p>";       // Down button, state in italics

            s += "</body>";                                             // close the body section

            s += "</html>";                                             // close the page type

            return s;

        }

        public static void Main()
        {
            // First, make sure we actually have a network interface to work with!
            if (Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces().Length < 1)
            {

                Debug.Print("No Active network interfaces. Bombing out.");
                Thread.CurrentThread.Abort();
            }

            // OK, retrieve the network interface
            Microsoft.SPOT.Net.NetworkInformation.NetworkInterface NI = Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];


            // If DHCP is not enabled, then enable it and get an IP address, else renew the lease. Most iof us have a DHCP server

            // on a network, even at home (in the form of an internet modem or wifi router). If you want to use a static IP

            // then comment out the following code in the "DHCP" region and uncomment the code in the "fixed IP" region.


            if (NI.IsDhcpEnabled == false)
            {

                Debug.Print("Enabling DHCP.");

                NI.EnableDhcp();

                Debug.Print("DCHP - IP Address = " + NI.IPAddress + " ... Net Mask = " + NI.SubnetMask + " ... Gateway = " + NI.GatewayAddress);

            }

            else
            {

                Debug.Print("Renewing DHCP lease.");

                NI.RenewDhcpLease();

                Debug.Print("DCHP - IP Address = " + NI.IPAddress + " ... Net Mask = " + NI.SubnetMask + " ... Gateway = " + NI.GatewayAddress);

            }

            // Create the socket            
            Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


            // Bind the listening socket to the port

            IPAddress hostIP = IPAddress.Parse(NI.IPAddress);

            IPEndPoint ep = new IPEndPoint(hostIP, 80);

            listenSocket.Bind(ep);

            // Start listening
            listenSocket.Listen(1);


            

            // Main thread loop

            while (true)
            {

                try
                {

                    Debug.Print("listening...");

                    Socket newSock = listenSocket.Accept();

                    Debug.Print("Accepted a connection from " + newSock.RemoteEndPoint.ToString());

                    byte[] messageBytes = Encoding.UTF8.GetBytes(ButtonPage(NI.IPAddress));

                    newSock.Send(messageBytes);

                    Thread.Sleep(100);

                    newSock.Close();

                }

                catch (Exception e)
                {

                    Debug.Print(e.Message);

                }

            }

 
               
        }

    }
}



@ ISuck@ Starcraft2 -

sorry, I don’t complete understand your idea, if it is possible, can you change the codes in the example codes and show me, how can I use the “using (Socket s = new Socket(…))”?

@ Workhard, sorry, I think you’re crazy expecting a 1 second refresh to do anything sensible. If you did that at 5 second interval you’re probably cutting it fine, at 10 seconds you’re probably ok.

Think about the communicaiton. The browser has to establish a TCP/IP connection to the device, then open the HTTP session, then generate and transfer the data in the response. You would not reliably get that done in a second, I can see TCP retries making that fall past a second, plus I can see that browsers handling that within a second would also be pushing it to guarantee to be ready before the refresh timer triggered.

What are you trying to achieve?

Why don’t you start by doing something more reasonable as a refresh time and see how things react.

@ Brett -

thank you for your answer!

I have tried 5 second interval and 10 second interval in webbrowser “IE”, “Firefox” and “Chrome”, I find that

the “refresh” runs only about 30 times and then “refresh” stopt.

If time interval is too lang, I can’t see the 3 buttons press or release in time.

I suspect that webbrowser stop the refresh.

Can you try my codes in your Visual Studio please? and you can know what I mean.

Why is

sleep(100);

in there? I would try and remove it, and go at least a 2 second refresh.

I’d move close to finally to make sure it happens.

finally
{
newSock.Close();
}

Are you ever seeing debug exceptions? I’m wondering if it can’t keep up with requests and then you’re just timing out.

sorry for the late response…my initial thought was that your sockets were not being disposed of properly and that they were remaining open longer than they should…eventually using up all ports. Since sockets implement disposable you can try the change below

[quote]
using (Socket newSocket = listenSocket.Accept())
{
Debug.Print(“listening…”);
Socket newSock = listenSocket.Accept();
Debug.Print("Accepted a connection from " + newSock.RemoteEndPoint.ToString());
byte messageBytes = Encoding.UTF8.GetBytes(ButtonPage(NI.IPAddress));
newSock.Send(messageBytes);
newSock.Close();
}[/quote]

Some other notes…
-i think sockets by default block, so socket.Accept will block until a connection is available. this is why you see the code sometimes stop there, this also implies that ‘something’ has stopped trying to make a connection (perhaps its waiting for a port to free up?)
-as Dr9 suggests, i would remove the sleep…i don’t think u need it since socket will block on the accept the next loop

the other thing you can do is also install some sniffer and sniff the ip the ‘web server’ is bound to. it should provide some valuable info regarding the packets and negotiations…
i’ve used Ethereal in the past for this…but have heard good things about fiddler also.

Fiddler is EXCELLENT - can even capture https (if you install local certs).

I think it is a resource issue, would be helpful to capture any errors thrown to debug.