Main Site Documentation

Is a Web Server this easy?


#1

Technically i should not even be attempting anything like this so soon with my knowledge level of .netmf
But reading gets boring after a while and i gotta try something to keep it exciting.

If anyone is bored enough to have a lookse at it and tell me if i am at least closing the connection properly. I know things could be made better, but i am more concerned about proper opening and closing connection.


using System;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.Net;
using System.Net;


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


using GHIElectronics.NETMF.FEZ;

namespace FEZ_Cobra_Console_Application2
{
    public class Program
    {
        public static void Main()
        {
            HttpListenerContext context;
            HttpListenerRequest request;
            HttpListenerResponse response;


            new Thread(LedBlinker).Start();


            HttpListener myListener = new HttpListener("http", -1);
            myListener.Start();


            while (true)
            {
                

                try
                {
                    Debug.Print("Waiting for Request");
                    context = myListener.GetContext();

                    request = context.Request;
                    response = context.Response;

                    // Just show some info so i know whats going on. 
                    Debug.Print("Request From:" + request.UserHostAddress);
                    Debug.Print("Keep Alive:" + request.KeepAlive);
                    Debug.Print("URL Raw:" + request.RawUrl);
                    Debug.Print("Input Stream:" + request.InputStream);
                    Debug.Print("http Method:" + request.HttpMethod);
                    Debug.Print("Content Length:" + request.ContentLength64);
                    Debug.Print("Content Type:" + request.ContentType);

                    //Not sure what the heck this does yet, or if needed. 
                    response.StatusCode = (int)HttpStatusCode.OK;

                    string myResponse;

                    myResponse = "<html xmlns='http://www.w3.org/1999/xhtml'>\r\n";
                    myResponse += "<head>\r\n";
                    myResponse += "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />\r\n";
                    myResponse += "<title>Untitled Document</title>\r\n";
                    myResponse += "\r\n";
                    myResponse += "</head>\r\n";
                    myResponse += "\r\n";
                    myResponse += "<body>\r\n";
                    myResponse += "<p>&nbsp;</p>\r\n";
                    myResponse += "<p>&nbsp;</p>\r\n";
                    myResponse += "<p>&nbsp;</p>\r\n";
                    myResponse += "<p align='center'><strong>Hello World</strong></p>\r\n";
                    myResponse += "<p align='center'>&nbsp;</p>\r\n";
                    myResponse += "</body>\r\n";
                    myResponse += "</html>\r\n";

                    // Yam the string into bytes
                    byte[] buffer = Encoding.UTF8.GetBytes(myResponse);
                    
                    // Het the length
                    response.ContentLength64 = buffer.Length;

                    try
                    {
                        using (Stream output = response.OutputStream)
                            output.Write(buffer, 0, buffer.Length);

                            // I dont think this is necessary, because the "using" closes this?
                            response.Close();

                    }
                    catch (Exception)
                    {
                        Debug.Print("Crap!");
                        
                    }

                }
                catch
                {

                    Debug.Print("Double Crap!");
                
                }

                // Sleep for 50 milliseconds
                Thread.Sleep(50);
            }
        }


        //Just blink the onboard led so i know we are running 
        static void LedBlinker()
        {
            bool ledState = false;
            Microsoft.SPOT.Hardware.OutputPort led = new Microsoft.SPOT.Hardware.OutputPort((Microsoft.SPOT.Hardware.Cpu.Pin)FEZ_Pin.Digital.LED, ledState);

            while (true)
            {
                // Sleep for 500 milliseconds
                Thread.Sleep(250);

                // toggle LED state
                ledState = !ledState;
                led.Write(ledState);

            }
        }


    }
}




#2

If you want a webserver on the cobra, consider the code written by Wouter Huysentruit: http://code.tinyclr.com/project/243/webserver-extension-for-fez-cobra/


#3

Hi jdal,

For what I watched in your code (I had only a few minutes), you are not closing the context and response object properly. So it may work for some pages, but you are at high risks of getting memory leaks and “OutOf Memory” exeptions after some time. Also, your catchings are incomplete.

I agree with Eric, why not looking at existing examples ?
Such as Wouter’s for Cobra,
Mine for UsbUzi (Fez panda, domino mini)
Or microsoft’s for general HttpListener use (on your harddrive)

To be honest, that is not that simple at it appears to be. Yes, it is easy to make it work as you did. But if you want some code that will correctly catch all possible exeptions, do not leak, recovers for uncompletly closed sockets, and so on, so a code that will be able to run for weeks (or months) without crashing, it takes time to tune it up… As usual, the smallest details take the longest time to tune !

Good luck and HAVE FUN ! :smiley:


#4

I have looked at the code by Wouter Huysentruit, and a few others. I want to build up to that level so this way i will have a full understanding rather than just copy and paste.

@ Nicolas3, [quote]you are not closing the context and response object properly.[/quote]
isn’t the response.Close(); doing that ? or no, i need something else.


#5

You may need to also close the context;
Also, the place where you are doing it is not appropriate:
within your main while() loop, you first do a try block where you open context and response object. At the end of this try block, you are closing the response. But what happens if something fails in the middle ? You may have opened some objects (context, request, response) and not closed them. That will result in some memory leakage in case of a socket would close before you issue the response. And believe me, that happens quite a bit “in real life”…

Please have a look here : http://code.tinyclr.com/project/243/webserver-extension-for-fez-cobra/