Webserver

I picked up this awesome webserver from the Netduino forums - Another Web Server - Project Showcase - Netduino Forums

I’ve used it for years on Netduino projects. Recently I needed more RAM for my project and moved over to a G120.
I’ve had the PCB’s made and connected an ENC28 module successfully. It appears to be working except I can’t get a good webserver going. I keep running into this bug. https://www.ghielectronics.com/community/forum/topic?id=17222&page=1#msg171641

I can’t really be bothered with it and decided to re-use my old Netduino code. What I can’t figure out is how to “connect” this socket listener to my enc28 module.

here is the code I use to set up the enc28


class Setup
    {
        public static EthernetENC28J60 enc;
        static bool hasAddress = false;
        static bool available = false;

        public static void Initilise()
        {

            NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged; 
            NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
 

            enc = new GHI.Networking.EthernetENC28J60(SPI.SPI_module.SPI1,
                GHI.Pins.G120.P1_10, // chip select    
                GHI.Pins.G120.P0_11, // interrupt    
                GHI.Pins.G120.P0_5   // reset    
                );
            enc.Open(); 
            enc.EnableStaticIP("10.0.0.100", "255.255.255.0", "10.0.0.1"); 
            enc.EnableStaticDns(new string[] { "10.0.0.1" });

            while (!hasAddress || !available) 
            { 
                Debug.Print("Initializing"); 
                System.Threading.Thread.Sleep(100); 
            } 
        }

        private static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            Debug.Print("Network available: " + e.IsAvailable.ToString());
            available = e.IsAvailable;
        }

        private static void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            Debug.Print("The network address has changed."); 
            hasAddress = enc.IPAddress != "0.0.0.0";
            Debug.Print(enc.IPAddress.ToString());
        }
    }

Here is the webserver code.


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

using G120.Tools.FileManagement;

namespace G120.SAL.Eth
{
    public delegate void WebRequest(Request request);

    public class Server
    {
        public Server(int port, WebRequest userRequester)
        {
            using (System.Net.Sockets.Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                socket.Bind(new IPEndPoint(IPAddress.Any, port));
                socket.Listen(10);
                Log.Print("Http Server: Listening on address " + Detect.Eth_IP());
                while (true)
                {
                    try
                    {
                        using (Socket client = socket.Accept())
                        {
                            if (client.Poll(5000000, SelectMode.SelectRead))
                            {
                                if (client.Available > 0) new HttpRequester(client, userRequester);
                            }
                        }
                    }
                    catch { }
                }
            }
        }
    }

    public class HttpRequester : IDisposable
    {
        const int bufLen = 512;

        public void Dispose() 
        { 

        }

        public object[] Arguments { get; set; }

        public HttpRequester(Socket client, WebRequest userRequester)
        {
            using (client)
            {
                byte[] buffer = new byte[client.Available];
                int count = client.Receive(buffer);
                string s = new string(Encoding.UTF8.GetChars(buffer));
                Request request = new Request(client, s);

                string[] parts = request.url.Split('/');
                string command = null;
                string argument = null;
                string values = null;

                // Parse first part to command
                if (parts.Length == 2)
                {
                    command = parts[1].ToString();
                }
                if (parts.Length == 3)
                {
                    command = parts[1].ToString();
                    argument = parts[2].ToString();
                }
                if (parts.Length == 4)
                {
                    command = parts[1].ToString();
                    argument = parts[2].ToString();
                    values = parts[3].ToString();
                }

                if (userRequester != null) userRequester(request);
                else
                {	// this is skipped if userRequest is implemented
                    //if (request.url == "/") command = "menu";
                    switch (command)
                    {
                        case "test":
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes("You have shown a status blink of " + argument + " second.")));
                                Sally.StatusLED[1].Write(true);
                                Thread.Sleep(Convert.ToInt32(argument));
                                Sally.StatusLED[1].Write(false);
                            }
                            break;

                        case "/dir":
                            {
                                request.sendFileBrowser();
                            }
                            break;

                        case "log":
                            if (argument == "" || argument == null)
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes(/*Java.Refresh(10) + */"Most Recent on TOP<br /><br />" + Log.Read(0))));
                                //Log.Print("Memory: " + Microsoft.SPOT.Debug.GC(false).ToString());
                            }
                            else if (argument == "errors")
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes(/*Java.Refresh(10) + */"Most Recent on TOP<br /><br />" + Log.Read(1))));
                            }
                            else if (argument == "erase")
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes(/*Java.Refresh(10) + */"Most Recent on TOP<br /><br />" + Log.Read(0))));
                                Log.Erase(0);
                                Log.Erase(1);
                            }
                            else
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes(command.ToString() + " " + argument.ToString() + @ " is not a valid command. Try menu/index.html")));
                            }
                            break;
                    }
                }
            }
        }
    }

    public class Request
    {
        public Socket client;
        private string _url;
        private string _argString;
        private string[] _key;
        private string[] _value;

        public Request(Socket Client, string data)
        {
            client = Client;
            if (data == null) data = "";
            string[] parms = data.Trim().Split(' ');
            string[] f = parms[1].Split('?');
            _url = f[0].ToLower();
            if (f.Length > 1) _argString = f[1].Trim(); else _argString = "";
            _key = _argString.Split('&');
            if (_key.Length == 1) if (_key[0] == "") _key = new string[0];
            _value = new string[_key.Length];
            for (int i = 0; i < _key.Length; i++)
            {
                string[] p = _key[i].Split('=');
                if (p.Length > 1) _value[i] = p[1].Trim(); else _value[i] = "";
                if (p.Length > 0) _key[i] = p[0].Trim().ToLower(); else _key[i] = "";
            }
        }

        public string url { get { return _url; } set { _url = value; } }

        public string path { get { return _url.toFullPath(); } set { _url = value.toUrl(); } }

        public string[] key { get { return _key; } }

        public string[] value { get { return _value; } }

        public string getKey(string key)
        {
            for (int i = 0; i < _key.Length; i++) if (key.ToLower() == _key[i]) return value[i];
            return "";
        }

        public string contextType
        {
            get
            {
                if (_url == "/") return "text/html";
                switch (_url.Substring(_url.LastIndexOf('.') + 1).ToLower())
                {
                    case "html":
                    case "htm": return "text/html";
                    case "css": return "text/css";
                    case "xml":
                    case "xsl": return "text/xml";
                    case "jpg":
                    case "jpeg": return "image/jpeg";
                    case "gif": return "image/gif";
                    case "json": return "application/json";
                    case "xhtml": return "application/xhtml+xml";
                    case "png": return "image/png";
                    case "ico": return "image/ico";
                    case "js": return "application/javascript";
                    case "gz":
                    case "zip": return "application/zip";
                    case "pdf": return "application/pdf";
                    case "mp3": return "audio/mpeg";
                    case "csv": return "text/csv";
                    case "txt":
                    default: return "text/plain";
                }
            }
        }

        const int bufLen = 512;
        public void sendStream(Stream stream)
        {
            byte[] buffer = new byte[bufLen];
            using (Stream inputStream = stream)
            {
                client.Send(Encoding.UTF8.GetBytes("HTTP/1.1 200 OK\r\nContent-Type: " + contextType + "; charset=utf-8\r\n" +
                    "Content-Length: " + inputStream.Length.ToString() + "\r\n" +
                    "\r\n" + "Connection: Close\r\n\r\n"));
                while (true)
                {
                    int bytesRead = inputStream.Read(buffer, 0, bufLen);
                    if (bytesRead == 0) break;
                    client.Send(buffer, bytesRead, SocketFlags.None);
                    Thread.Sleep(10);
                }
            }
        }

        public void sendFileBrowser()
        {
            string dir = getKey("dir").toFullPath();
            msgStream sdr = new msgStream(this);
            sdr.Write("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n");
            sdr.Write("Connection: Close\r\n\r\n");
            sdr.Write("<html><body><h2>Directory Browser: " + dir + "</h2><table style=\"font-family: 'Courier New', Courier, monospace; font-size: x-small\">");
            sdr.Write("<tr><th align='left'>Name:</th><th align='right'></th><th></th></tr>");
            if (!dir.isRoot())
                sdr.Write("<tr><td><<a href='dir?dir=" + dir.Substring(0, dir.LastIndexOf('\\')).toUrl() + "'>../</a>></td><td></td><td></td></tr>");
            DirectoryInfo di = new DirectoryInfo(dir);
            DirectoryInfo[] disub = di.GetDirectories();
            foreach (DirectoryInfo dii in disub) { sdr.Write("<tr><td><<a href='dir?dir=" + dii.FullName.toUrl() + "'>" + dii.Name + "</a>></td><td></td></tr>"); }
            sdr.Write("<tr><th align='left'>Name:</th><th align='right'>Length:</th><th>Last modified:</th></tr>");
            FileInfo[] rgFiles = di.GetFiles();
            foreach (FileInfo fi in rgFiles) { sdr.Write("<tr><td><a href='" + fi.FullName.Substring(HttpHelper.SD_Root.Length) + "'>" + fi.Name + "</a></td><td align='right'>" + fi.Length + "</td><td>" + fi.LastWriteTime.ToString() + "</td></tr>"); }
            sdr.Write("<tr><th align='left'>Build in:</th><th></th></tr>");
            sdr.Write("<tr><td><a href=\"/\">Default page</a></td><td align='right'></td></tr>");
            sdr.Write("<tr><td><a href=\"/fields.json\">Fields.JSON</a></td><td align='right'></td></tr>");
            sdr.Write("</table></body></html>");
            sdr.Flush();
        }

        public void sendFileNotFound()
        {	//	Send 404 - not found
            client.Send(Encoding.UTF8.GetBytes("HTTP/1.1 404 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n" + "Connection: Close\r\n\r\n"));
        }

        public class msgStream
        {
            private string _buffer;
            Request _request;
            public msgStream(Request request)
            {
                _request = request;
                _buffer = "";
            }
            public void Flush()
            {
                if (_buffer.Length > 0) _request.client.Send(Encoding.UTF8.GetBytes(_buffer));
                _buffer = "";
            }
            public void Write(string buf)
            {
                _buffer += buf;
                if (_buffer.Length > bufLen) Flush();
            }
        }
    }

    public static class HttpHelper
    {
        public const string SD_Root = @ "\SD\www";
        public const int bufLen = 512;

        public static string toFullPath(this string url)
        {
            string s = SD_Root.TrimEnd('\\') + '\\';
            int p = 0;
            if (p < url.Length) { if ((url[0] == '\\') | (url[0] == '/')) p++; }
            while (p < url.Length)
            {
                if ((url[p] == '\\') | (url[p] == '/')) s += '\\'; else s += url[p];
                p++;
            }
            return s;
        }

        public static string toUrl(this string path)
        {
            int p = SD_Root.TrimEnd('\\').Length;
            string s = "";
            while (p < path.Length)
            {
                if (path[p] == '\\') s += '/'; else s += path[p];
                p++;
            }
            return s;
        }

        public static bool isRoot(this string path)
        {
            return (path == (SD_Root.TrimEnd('\\') + '\\'));
        }
    }
}

So as long as I’ve got an ip from the enc28 module. This line is what binds the socket to that address.


socket.Bind(new IPEndPoint(IPAddress.Any, port));

Thanks for the help, Still no luck with my trusty ol’ web server though. Maybe time to put it into retirement.

I’m not sure to be honest. If I execute it on the Netduino Plus 2. I can connect to it just by entering the ip address in the browser. :-[

But I’m not an expert at these things. Going to the ip address of the cobra yields nothing. The networking appears to be ok, in that it can get an ip address from my dhcp server and it appears in the lease list.

I’m not sure where else to go next to be honest. Maybe i’ll try something based on http listener.

OK, Didn’t know I could do that with setting up an ICMP listener or something.

But yeah, now I’ve tried it, and I can ping it.

Thanks,

In your code you use a static IP address, so DHCP shouldn’t be an issue.

When I used the statc IP address, I didn’t get the event for the IP address change. In your application it would mean that your programm will never leave the init loop and go to the web server part.

Oh Yeah, I fixed it and still no joy. This is the code i’m running now. I swapped to DHCP just to check that there weren’t other problems.



using System;
using System.Threading;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT;
using Microsoft.SPOT.Net;
using Microsoft.SPOT.Net.NetworkInformation;

using GHI.Pins;
using GHI.Networking;

namespace G120.SAL.Eth
{
    class Setup
    {
        public static EthernetENC28J60 enc;
        static bool hasAddress = false;
        static bool available = false;

        public static void Initilise()
        {

            NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged; 
            NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
 

            enc = new GHI.Networking.EthernetENC28J60(SPI.SPI_module.SPI1,
                GHI.Pins.G120.P1_10, // chip select    
                GHI.Pins.G120.P0_11, // interrupt    
                GHI.Pins.G120.P0_5   // reset    
                );
            enc.EnableDhcp();
            enc.EnableDynamicDns();

            enc.Open();
            //enc.RefreshNetworkInterface();
            //enc.EnableStaticIP("10.0.0.5", "255.255.255.192", "10.0.0.1"); 
            //enc.EnableStaticDns(new string[] { "10.0.0.1" });

            while (enc.IPAddress == "0.0.0.0")
            {
                Thread.Sleep(100);
            }

            Debug.Print(enc.IPAddress.ToString());

        }

        private static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            Debug.Print("Network available: " + e.IsAvailable.ToString());
            available = e.IsAvailable;
        }

        private static void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            Debug.Print("The network address has changed."); 
            hasAddress = enc.IPAddress != "0.0.0.0";
        }
    }
}



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

using G120.Tools.FileManagement;

namespace G120.SAL.Eth
{
    public delegate void WebRequest(Request request);

    public class Server
    {
        public Server(int port, WebRequest userRequester)
        {
            using (System.Net.Sockets.Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                socket.Bind(new IPEndPoint(IPAddress.Any, port));
                socket.Listen(10);
                Log.Print("Http Server: Listening on address " + Detect.Eth_IP());
                while (true)
                {
                    try
                    {
                        using (Socket client = socket.Accept())
                        {
                            if (client.Poll(5000000, SelectMode.SelectRead))
                            {
                                if (client.Available > 0) new HttpRequester(client, userRequester);
                            }
                        }
                    }
                    catch { }
                }
            }
        }
    }

    public class HttpRequester : IDisposable
    {
        const int bufLen = 512;

        public void Dispose() 
        { 

        }

        public object[] Arguments { get; set; }

        public HttpRequester(Socket client, WebRequest userRequester)
        {
            using (client)
            {
                byte[] buffer = new byte[client.Available];
                int count = client.Receive(buffer);
                string s = new string(Encoding.UTF8.GetChars(buffer));
                Request request = new Request(client, s);

                string[] parts = request.url.Split('/');
                string command = null;
                string argument = null;
                string values = null;

                // Parse first part to command
                if (parts.Length == 2)
                {
                    command = parts[1].ToString();
                }
                if (parts.Length == 3)
                {
                    command = parts[1].ToString();
                    argument = parts[2].ToString();
                }
                if (parts.Length == 4)
                {
                    command = parts[1].ToString();
                    argument = parts[2].ToString();
                    values = parts[3].ToString();
                }

                if (userRequester != null) userRequester(request);
                else
                {	// this is skipped if userRequest is implemented
                    //if (request.url == "/") command = "menu";
                    switch (command)
                    {
                        case "test":
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes("You have shown a status blink of " + argument + " seconds.")));
                                Sally.StatusLED[1].Write(true);
                                Thread.Sleep(Convert.ToInt32(argument) * 1000);
                                Sally.StatusLED[1].Write(false);
                            }
                            break;

                        case "dir":
                            {
                                request.sendFileBrowser();
                            }
                            break;

                        case "log":
                            if (argument == "" || argument == null)
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes(/*Java.Refresh(10) + */"Most Recent on TOP<br /><br />" + Log.Read(0))));
                                //Log.Print("Memory: " + Microsoft.SPOT.Debug.GC(false).ToString());
                            }
                            else if (argument == "errors")
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes(/*Java.Refresh(10) + */"Most Recent on TOP<br /><br />" + Log.Read(1))));
                            }
                            else if (argument == "erase")
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes(/*Java.Refresh(10) + */"Most Recent on TOP<br /><br />" + Log.Read(0))));
                                Log.Erase(0);
                                Log.Erase(1);
                            }
                            else
                            {
                                request.sendStream(new MemoryStream(Encoding.UTF8.GetBytes(command.ToString() + " " + argument.ToString() + @ " is not a valid command. Try menu/index.html")));
                            }
                            break;
                    }
                }
            }
        }
    }

    public class Request
    {
        public Socket client;
        private string _url;
        private string _argString;
        private string[] _key;
        private string[] _value;

        public Request(Socket Client, string data)
        {
            client = Client;
            if (data == null) data = "";
            string[] parms = data.Trim().Split(' ');
            string[] f = parms[1].Split('?');
            _url = f[0].ToLower();
            if (f.Length > 1) _argString = f[1].Trim(); else _argString = "";
            _key = _argString.Split('&');
            if (_key.Length == 1) if (_key[0] == "") _key = new string[0];
            _value = new string[_key.Length];
            for (int i = 0; i < _key.Length; i++)
            {
                string[] p = _key[i].Split('=');
                if (p.Length > 1) _value[i] = p[1].Trim(); else _value[i] = "";
                if (p.Length > 0) _key[i] = p[0].Trim().ToLower(); else _key[i] = "";
            }
        }

        public string url { get { return _url; } set { _url = value; } }

        public string path { get { return _url.toFullPath(); } set { _url = value.toUrl(); } }

        public string[] key { get { return _key; } }

        public string[] value { get { return _value; } }

        public string getKey(string key)
        {
            for (int i = 0; i < _key.Length; i++) if (key.ToLower() == _key[i]) return value[i];
            return "";
        }

        public string contextType
        {
            get
            {
                if (_url == "/") return "text/html";
                switch (_url.Substring(_url.LastIndexOf('.') + 1).ToLower())
                {
                    case "html":
                    case "htm": return "text/html";
                    case "css": return "text/css";
                    case "xml":
                    case "xsl": return "text/xml";
                    case "jpg":
                    case "jpeg": return "image/jpeg";
                    case "gif": return "image/gif";
                    case "json": return "application/json";
                    case "xhtml": return "application/xhtml+xml";
                    case "png": return "image/png";
                    case "ico": return "image/ico";
                    case "js": return "application/javascript";
                    case "gz":
                    case "zip": return "application/zip";
                    case "pdf": return "application/pdf";
                    case "mp3": return "audio/mpeg";
                    case "csv": return "text/csv";
                    case "txt":
                    default: return "text/plain";
                }
            }
        }

        const int bufLen = 512;
        public void sendStream(Stream stream)
        {
            byte[] buffer = new byte[bufLen];
            using (Stream inputStream = stream)
            {
                client.Send(Encoding.UTF8.GetBytes("HTTP/1.1 200 OK\r\nContent-Type: " + contextType + "; charset=utf-8\r\n" +
                    "Content-Length: " + inputStream.Length.ToString() + "\r\n" +
                    "\r\n" + "Connection: Close\r\n\r\n"));
                while (true)
                {
                    int bytesRead = inputStream.Read(buffer, 0, bufLen);
                    if (bytesRead == 0) break;
                    client.Send(buffer, bytesRead, SocketFlags.None);
                    Thread.Sleep(10);
                }
            }
        }

        public void sendFileBrowser()
        {
            string dir = getKey("dir").toFullPath();
            msgStream sdr = new msgStream(this);
            sdr.Write("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n");
            sdr.Write("Connection: Close\r\n\r\n");
            sdr.Write("<html><body><h2>Directory Browser: " + dir + "</h2><table style=\"font-family: 'Courier New', Courier, monospace; font-size: x-small\">");
            sdr.Write("<tr><th align='left'>Name:</th><th align='right'></th><th></th></tr>");
            if (!dir.isRoot())
                sdr.Write("<tr><td><<a href='dir?dir=" + dir.Substring(0, dir.LastIndexOf('\\')).toUrl() + "'>../</a>></td><td></td><td></td></tr>");
            DirectoryInfo di = new DirectoryInfo(dir);
            DirectoryInfo[] disub = di.GetDirectories();
            foreach (DirectoryInfo dii in disub) { sdr.Write("<tr><td><<a href='dir?dir=" + dii.FullName.toUrl() + "'>" + dii.Name + "</a>></td><td></td></tr>"); }
            sdr.Write("<tr><th align='left'>Name:</th><th align='right'>Length:</th><th>Last modified:</th></tr>");
            FileInfo[] rgFiles = di.GetFiles();
            foreach (FileInfo fi in rgFiles) { sdr.Write("<tr><td><a href='" + fi.FullName.Substring(HttpHelper.SD_Root.Length) + "'>" + fi.Name + "</a></td><td align='right'>" + fi.Length + "</td><td>" + fi.LastWriteTime.ToString() + "</td></tr>"); }
            sdr.Write("<tr><th align='left'>Build in:</th><th></th></tr>");
            sdr.Write("<tr><td><a href=\"/\">Default page</a></td><td align='right'></td></tr>");
            sdr.Write("<tr><td><a href=\"/fields.json\">Fields.JSON</a></td><td align='right'></td></tr>");
            sdr.Write("</table></body></html>");
            sdr.Flush();
        }

        public void sendFileNotFound()
        {	//	Send 404 - not found
            client.Send(Encoding.UTF8.GetBytes("HTTP/1.1 404 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n" + "Connection: Close\r\n\r\n"));
        }

        public class msgStream
        {
            private string _buffer;
            Request _request;
            public msgStream(Request request)
            {
                _request = request;
                _buffer = "";
            }
            public void Flush()
            {
                if (_buffer.Length > 0) _request.client.Send(Encoding.UTF8.GetBytes(_buffer));
                _buffer = "";
            }
            public void Write(string buf)
            {
                _buffer += buf;
                if (_buffer.Length > bufLen) Flush();
            }
        }
    }

    public static class HttpHelper
    {
        public const string SD_Root = @ "\SD\www";
        public const int bufLen = 512;

        public static string toFullPath(this string url)
        {
            string s = SD_Root.TrimEnd('\\') + '\\';
            int p = 0;
            if (p < url.Length) { if ((url[0] == '\\') | (url[0] == '/')) p++; }
            while (p < url.Length)
            {
                if ((url[p] == '\\') | (url[p] == '/')) s += '\\'; else s += url[p];
                p++;
            }
            return s;
        }

        public static string toUrl(this string path)
        {
            int p = SD_Root.TrimEnd('\\').Length;
            string s = "";
            while (p < path.Length)
            {
                if (path[p] == '\\') s += '/'; else s += path[p];
                p++;
            }
            return s;
        }

        public static bool isRoot(this string path)
        {
            return (path == (SD_Root.TrimEnd('\\') + '\\'));
        }
    }
}


Do you see the output of this line?

10.0.0.54

Huh! I can tap that web page from another PC? Wait a minute… :wall: :wall: :wall: :wall: :wall: :wall: :wall:

Proxy settings were killing it.

I’m so sorry for wasting your time.

The directory browser works. But I can’t open my .txt files once I navigate to them. But that’s ok for now. Great little webserver this one. Hope someone else finds it useful.

Thanks again for all your time.

You could use mIP. It was specifically built for the enc28j60. You would have to use a firmware build that excludes the Ethernet driver. The code and samples are at mip.codeplex.com