Write a simple Web Server in C#
Writing a simple Web Server is actually a breeze. If we just want to host some HTML pages, we can do this:
Create a C# console program in VS2013
Write a string extension method class, mainly used to intercept file names in the URL
ExtensionMethods.cs
Using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
Namespace webserver1
{
/// <summary>
/// Some useful string extension methods
/// </summary>
public static class ExtensionMethods
{
/// <summary>
/// returns the string to the left of the given string or the entire source string
/// </summary>
/// <param name="src"> source string </param>
/// <param name="s"> Compare string </param>
/// <returns></returns>
public static string LeftOf( this String src, string s)
{
String ret = src;
int idx = src.IndexOf(s);
if (idx != - 1 ) { ret = src.Substring( 0 , idx); }
return ret;
}
/// <summary>
/// returns the string to the right of the given string or the entire source string
/// </summary>
/// <param name="src"> source string </param>
/// <param name="s"> Compare string </param>
/// <returns></returns>
public static string RightOf( this String src, string s)
{
String ret = String.Empty;
int idx = src.IndexOf(s);
if (idx != - 1 ) {
Ret = src.Substring(idx + s.Length);
} return ret;
}
}
}
Enable HTTP listening in the portal program
Program.cs
Using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Net;
using System.IO;
Namespace webserver1
{
Class Program
{
Static Semaphore sem;
Static void Main( string [] args)
{
/ / Support to simulate 20 connections
sem = new Semaphore ( 20 , 20 );
HttpListener listener = new HttpListener();
string url = " http://localhost/ " ;
listener.Prefixes.Add(url);
listener.Start();
Task.Run(() =>
{
While ( true ) {
sem.WaitOne();
StartConnectionListener(listener);
}
});
Console.WriteLine( " Click any key to exit WebServer " );
Console.ReadLine();
}
Static async void StartConnectionListener(HttpListener listener)
{
// wait for the connection.
HttpListenerContext context = await listener.GetContextAsync();
/ / Release the annunciator, another listener can immediately open
sem.Release ();
/ / Get the request object
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
// Capture the file name on the URL path, between "/" and "?"
string path = request.RawUrl.LeftOf( " ? " ).RightOf( " / " );
Console.WriteLine(path);
/ / Output some content
try
{
// Load the file and return it in UTF-8 encoding
string text = File.ReadAllText(path);
byte [] data = Encoding.UTF8.GetBytes(text);
response.ContentType = " text/html " ;
response.ContentLength64 = data.Length;
response.OutputStream.Write(data, 0 , data.Length);
response.ContentEncoding = Encoding.UTF8;
response.StatusCode = 200 ;
response.OutputStream.Close();
}
Catch (Exception ex) { Console.WriteLine(ex.Message); }
}
}
}
The above code initializes 20 listeners. Using a Semaphore, when a request is received, an annunciator is released and a new listener is created again. This server can receive 20 requests simultaneously. Use the await mechanism to handle whether the thread continues to run. If you are not familiar with the use of Task, async/await, it is recommended to refer to some documents.
Create an HTML file and set the property {copy to input directory} to “copy if newer”
Index.html
<html>
<head>
<title>Simple WebServer</title>
</head>
<body>
<p>Hello World</p>
</body>
</html>
Entire directory structure
Run the console program and enter the address in your browser:
If the browser cannot access localhost, edit the C:\Windows\System32\drivers\etc\hosts file to ensure that there is such a record.
127.0 . 0.1 localhost
Comment disabled