Creating a Webserver
The following sample code is a roughly edited and stripped down excerpt from a server class I wrote. Exception handling and a lot of extra data handling has been removed and names made a little more generic, to provide the idea of how to set up a basic server that can be built upon. I included some basic file handling and HTML returns and querystring parsing as well.
class WebServer { HttpListener Listener = new HttpListener(); public bool IsRunning {get; private set;} private string PORT; public void Start(string PORT, Form1 MainForm) { if (PORT == "") return; // Supported on current OS? if (!HttpListener.IsSupported) { MessageBox.Show("This OS is too old.","Sorry",MessageBoxButtons.OK,MessageBoxIcon.Hand); Environment.Exit(1); return; } // Set things up for starting. this.PORT = PORT; // Start hovedmotoren (main loop). Thread T = new Thread(new ThreadStart(WebMainLoop)); T.IsBackground = true; T.Start(); } private void WebMainLoop() { Listener.Prefixes.Add("http://+:"+ PORT +"/"); Listener.Start(); IsRunning = true; IAsyncResult AsyncResult; while (IsRunning) { // Wait for requests, then kick them off in their own thread. AsyncResult = Listener.BeginGetContext(new AsyncCallback(WebDoorman),Listener); AsyncResult.AsyncWaitHandle.WaitOne(); } // Stop() called, it lets the current iteration complete, // we then stop the listener here once loop is broken. Listener.Stop(); Listener.Prefixes.Clear(); } private void WebDoorman(IAsyncResult result) { // Receiving work as a callback function, reporting back. HttpListener DoormanListener = (HttpListener)result.AsyncState; HttpListenerContext context = DoormanListener.EndGetContext(result); // Thread started, Listener is ready for new requests. string ourHTML = ""; byte[] SendBackBuffer; Stream SendStream; string FullFileUrl = ""; int BytesRead = 0; /* Checking for GET data foreach (string _qsi in context.Request.QueryString.AllKeys) { // _qsi gives the key name. // context.Request.QueryString[_qsi] gives the key value. (?key=val) } // Is it a specific file that's requested? if ( context.Request.RawUrl.Contains(".png") || context.Request.RawUrl.Contains(".jpg") || context.Request.RawUrl.Contains(".gif") || context.Request.RawUrl.Contains(".ico") || context.Request.RawUrl.Contains(".css") || context.Request.RawUrl.Contains(".js") ) { FullFileUrl = "somefolder" + context.Request.RawUrl.Replace('/','\\'); FullFileUrl = FullFileUrl.Split('?')[0]; if (FullFileUrl.Contains(".png")) context.Response.ContentType = "image/png"; else if (FullFileUrl.Contains(".jpg")) context.Response.ContentType = "image/jpeg"; else if (FullFileUrl.Contains(".gif")) context.Response.ContentType = "image/gif"; else if (FullFileUrl.Contains(".css")) context.Response.ContentType = "text/css"; else if (FullFileUrl.Contains(".js")) context.Response.ContentType = "text/javascript"; else if (FullFileUrl.Contains(".ico")) context.Response.ContentType = "image/x-icon"; if (File.Exists(FullFileUrl)) { using (FileStream fs = File.OpenRead(FullFileUrl)) { context.Response.ContentLength64 = fs.Length; SendStream = context.Response.OutputStream; SendBackBuffer = new byte[64 * 1024]; // Send in 64 KB chunks. while ((BytesRead = fs.Read(SendBackBuffer,0,SendBackBuffer.Length)) > 0) { SendStream.Write(SendBackBuffer,0,BytesRead); } SendStream.Close(); } return; } else { context.Response.StatusCode = 404; ourHTML = missing(); SendBackBuffer = Encoding.UTF8.GetBytes(ourHTML); context.Response.ContentLength64 = SendBackBuffer.Length; context.Response.ContentType = "text/html"; SendStream = context.Response.OutputStream; SendStream.Write(SendBackBuffer,0,SendBackBuffer.Length); SendStream.Close(); } } // A HTML page if (context.Request.RawUrl.Contains("page1")) { ourHTML = HtmlSkeleton(context.Request.UserAgent,"page1.css","") + page1(); SendBackBuffer = Encoding.UTF8.GetBytes(ourHTML); context.Response.ContentLength64 = SendBackBuffer.Length; context.Response.ContentType = "text/html"; SendStream = context.Response.OutputStream; SendStream.Write(SendBackBuffer,0,SendBackBuffer.Length); SendStream.Close(); return; } // Another HTML page if (context.Request.RawUrl.Contains("page2")) { ourHTML = HtmlSkeleton(context.Request.UserAgent,"page2.css","page2.js") + page2(); SendBackBuffer = Encoding.UTF8.GetBytes(ourHTML); context.Response.ContentLength64 = SendBackBuffer.Length; context.Response.ContentType = "text/html"; SendStream = context.Response.OutputStream; SendStream.Write(SendBackBuffer,0,SendBackBuffer.Length); SendStream.Close(); return; } // Standard tilbakemelding hvis ingen andre aksjoner har blitt oppfanget. ourHTML = HtmlSkeleton(context.Request.UserAgent,"","") + "<b>WebServer Default Page.</b>"+ "</body></html>"; SendBackBuffer = Encoding.UTF8.GetBytes(ourHTML); context.Response.ContentLength64 = SendBackBuffer.Length; SendStream = context.Response.OutputStream; SendStream.Write(SendBackBuffer,0,SendBackBuffer.Length); SendStream.Close(); /* * Only care about errors if we're not shutting down. * Certain exceptions will be thrown regardless because of web clients * having orphaned AJAX calls and/or connections being broken from server * (i.e. restarts). We filter out the ones we experience during testing. * if ( !e.ToString().Contains("System.Net.HttpResponseStream.Write") && !e.ToString().Contains("System.NullReferenceException") && !e.ToString().Contains("System.ObjectDisposedException") ) // handle */ } private string page1() { string ReturnString = "<div id=\"Main\">"; // do content... ReturnString += "</div>"; return "</body></html>"+ ReturnString; } private string page2() { string ReturnString = "<div id=\"Main\">"; // do content... ReturnString += "</div>"; return "</body></html>"+ ReturnString; } public bool IsListening() { return Listener.IsListening; } private string Missing() { return "<!doctype html>"+ "<html>"+ "<head>"+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"+ "<link href=\"/CSS/missing.css\" rel=\"stylesheet\" type=\"text/css\">"+ "<title>Oops</title>"+ "</head>"+ "<body>"+ "<img src=\"/images/404.png\"><br>"+ "<b>404</b> - This link does not exist.<br><br>"+ "</body>"+ "</html>"; } private string HtmlSkeleton(string UserAgent, string cssCustomFile, string jsCustomFile) { string DocType = "<!doctype html>"; string cssFileName = "main.css"; string jsFileName = "main.js"; string HTML = ""+ "<html>"+ "<head>"+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"+ "<link rel=\"shortcut icon\" href=\"/Images/favicon.ico\" type=\"image/x-icon\">"+ "<link href=\"/CSS/"+ (cssCustomFile!=""?cssCustomFile:cssFileName) +" rel=\"stylesheet\" type=\"text/css\">"+ "<script src=\"/JS/"+ (jsCustomFile!=""?jsCustomFile:jsFileName) +" type=\"text/javascript\"></script>"+ "<title>MyWebServer</title>"; // do content... HTML +=""+ "</head>"+ "<body>"; return DocType + HTML; } public void Stop() { IsRunning = false; try { // Trigger a nonsense call to shut down any loop blocking listener. WebRequest webRequest = WebRequest.Create("http://127.0.0.1:" + PORT); WebResponse webResponse = webRequest.GetResponse(); } catch (Exception) {} } }