Dynamischer Auto Port HTTP Webserver unter C#

Dass man in .NET C# auch multithreaded HTTP Webserver schreiben kann, dürfte jedem klar sein.

Hier mal ein Klassenbeispiel, das automatisch einen freien Port ermittelt und den NAN_Webserver als Instant Webserver startet.
Wahlweise können PHP, Perl, etc als CGI-ausführende Programme deaklariert werden samt Dateitypen, sowie das Home-Verzeiichnis, und zwar alles direkt aus dem GUI-Designer heraus.

/*
 * Erstellt mit SharpDevelop.
 * Author: Holger Schadeck
 * Web: https://www.schadeck.eu
 */


using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Diagnostics;
using System.Threading;
using System.Collections;
using System.IO;


namespace libHSchadeck
{
    public class MimeTypeMap {
        public string Extension {
            get { return extension; }
            set { extension = value; }
        }
       
        public string MimeType {
            get { return mimeType; }
            set { mimeType = value; }
        }
       
        public bool IsBinary {
            get { return isBinary; }
            set { isBinary = value; }
        }
        private string extension;
        private string mimeType;
        private bool isBinary;
    }
    public class CgiExtension {
        public string Extension {
            get { return extension; }
            set { extension = value; }
        }
       
        public string ServerSubExecPath {
            get { return serverSubExecPath; }
            set { serverSubExecPath = value; }
        }
        private string extension;
        private string serverSubExecPath;
    }
    /// <summary>
    /// Description of NANWebserver.
    /// </summary>
    [SerializableAttribute]
    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
    public class NANWebserver : System.Windows.Forms.UserControl
    {
        private TcpListener listener;
        private IPAddress listenAddress = IPAddress.Parse("127.0.0.1");
        private int listenPortBase = 80;
        private int listenPort = 80;
        private string pathServer = "server";
        private string pathServerSubHome = "web";
        private string[] clientIps = new string[1];
        private string[] listenHosts = new string[2];
        private CgiExtension[] cgiExtensions = new CgiExtension[0];
        private Hashtable mimeMaps = new Hashtable();
        private Process serverProcess;
        private bool closeNow = false;
        public CgiExtension[] CgiExtensions {
            get { return cgiExtensions; }
            set { cgiExtensions = value; }
        }
        public int ListenPortBase {
            get { return listenPortBase; }
            set { listenPortBase = value; }
        }
        public string PathServer {
            get { return pathServer; }
            set { pathServer = value; }
        }
       
        public string PathServerSubHome {
            get { return pathServerSubHome; }
            set { pathServerSubHome = value; }
        }
        public string[] ClientIps {
            get { return clientIps; }
            set { clientIps = value; }
        }
        public string[] ListenHosts {
            get { return listenHosts; }
            set { listenHosts = value; }
        }
       
        public NANWebserver()
        {
            this.init();
           
        }
        private void init() {
            this.clientIps[0] = "all";
            this.listenHosts[0] = "127.0.0.1";
            this.listenHosts[1] = "localhost";
            this.addMimeTable("ai:1:application/postscript;aif:1:audio/x-aiff;aiff:1:audio/x-aiff;asc:0:text/plain;au:1:audio/basic;avi:1:video/x-msvideo;bin:1:application/octet-stream;bmp:1:image/bmp;css:1:text/css;doc:1:application/msword;dtd:0:application/xml-dtd;eps:1:application/postscript;exe:1:application/octet-stream;gif:1:image/gif;htm:0:text/html;html:0:text/html;jpe:1:image/jpeg;jpeg:1:image/jpeg;jpg:1:image/jpeg;js:0:application/x-javascript;mid:1:audio/midi;midi:1:audio/midi;mov:1:video/quicktime;mp2:1:audio/mpeg;mp3:1:audio/mpeg;mpe:1:video/mpeg;mpeg:1:video/mpeg;mpg:1:video/mpeg;mpga:1:audio/mpeg;pdf:1:application/pdf;png:1:image/png;ppt:1:application/vnd:ms-powerpoint;ps:1:application/postscript;qt:1:video/quicktime;ra:1:audio/x-realaudio;ram:1:audio/x-pn-realaudio;rm:1:audio/x-pn-realaudio;rpm:1:audio/x-pn-realaudio-plugin;snd:1:audio/basic;svg:1:image/svg:xml;swf:1:application/x-shockwave-flash;tif:1:image/tiff;tiff:1:image/tiff;txt:0:text/plain;wav:1:audio/x-wav;wml:0:text/vnd:wap:wml;xls:1:application/vnd:ms-excel;xml:0:application/xml;xsl:0:application/xml;xslt:0:application/xslt:xml;xul:1:application/vnd:mozilla:xul:xml;zip:1:application/zip");
        }
        public void addMimeTable(string table) {
            foreach(string line in table.Split(';')) {
                string[] cols = line.Trim().Split(':');
                this.addMimeType(cols[0],cols[2],((cols[1] == "1") ? true : false));
            }
        }
        public bool removeMimeType(string extension) {
            if(this.existMimeType(extension)) {
                this.mimeMaps.Remove(extension);
                return true;
            } else {
                return false;
            }
        }
        public bool existMimeType(string extension) {
            return this.mimeMaps.ContainsKey(extension);
        }
        public void addMimeType(string extension, string mimeType, bool binary) {
            if(this.existMimeType(extension)) {
                this.removeMimeType(extension);
            }
            MimeTypeMap map = new MimeTypeMap();
            map.Extension = extension;
            map.MimeType = mimeType;
            map.IsBinary = binary;
            this.mimeMaps.Add(extension, map);
        }
        private void writeTypes() {
            string file = this.pathServer+"\\types.txt";
            if(File.Exists(file)) {
                File.Delete(file);
            }
            string content = "";
            foreach(MimeTypeMap map in this.mimeMaps.Values) {
                content += map.Extension+"\t"+((map.IsBinary == true) ? "1" : "0") + "\t" + map.MimeType+Environment.NewLine;
            }
            File.WriteAllText(file, content);
        }
        private void writeSettings() {
            string file = this.pathServer+"\\settings.txt";
            if(File.Exists(file)) {
                File.Delete(file);
            }
            string content = "";
            content += "port="+this.listenPort+Environment.NewLine;
            content += "docroot="+this.pathServerSubHome+Environment.NewLine;
            foreach(string host in this.listenHosts) {
                content += "hostname="+host+Environment.NewLine;
            }
            foreach(string client in this.clientIps) {
                content += "clientip="+client+Environment.NewLine;
            }
            foreach(CgiExtension ext in this.cgiExtensions) {
                content += ext.Extension+"="+ext.ServerSubExecPath+Environment.NewLine;
            }
            File.WriteAllText(file, content);
        }
        public int Start() {
            int port = this.tryStart(this.listenPortBase);
            this.listenPort = port;
            if(!this.pathServer.Contains(":")) {
                this.pathServer = Environment.CurrentDirectory+"\"+this.pathServer;
            }
            this.writeTypes();
            this.writeSettings();
            this.startServer();
            return port;
        }
        public void Stop() {
            this.closeNow = true;
            try {
                this.serverProcess.Kill();
            } catch(Exception e) {
                Trace.WriteLine(e.Message);
            }
            try {
                string file = this.pathServer+"
\\settings.txt";
                File.Delete(file);
            } catch {
               
            }
            try {
                string file = this.pathServer+"
\\types.txt";
                File.Delete(file);
            } catch {
               
            }
           
        }
       
        private void startServer() {
            if(!this.closeNow) {
                this.serverProcess = new Process();
                this.initServer();
                this.serverProcess.Start();
            }
        }
       
        private void initServer() {
            string server = this.pathServer + "
\\nanweb.exe";
            this.serverProcess.StartInfo.WorkingDirectory = this.pathServer;
            this.serverProcess.StartInfo.FileName = server;
            this.serverProcess.StartInfo.Arguments = "
-s -m -bc=0";
            this.serverProcess.StartInfo.CreateNoWindow = true;
            this.serverProcess.EnableRaisingEvents = true;
            this.serverProcess.StartInfo.WindowStyle= ProcessWindowStyle.Hidden;
            this.serverProcess.StartInfo.UseShellExecute = false;
            this.serverProcess.Disposed+= delegate(object sender, EventArgs e) {
                if(!this.closeNow) {
                    this.startServer();
                }
            };
            this.serverProcess.Exited+= delegate(object sender, EventArgs e) {
                if(!this.closeNow) {
                    this.startServer();
                }
            };
           
        }
        private int tryStart(int port) {
            try {
                this.listener = new TcpListener(this.listenAddress, port) ;
                listener.Start();
                listener.Stop();
                return port;
            } catch {
                return this.tryStart(port+1);
            }
        }
       
    }
}

Nach Zuweisung der Werte im GUI-Editor beispielsweise folgenden Code für Formular einfügen:

void MainFormLoad(object sender, EventArgs e)
        {
            int port = this.nanWebserver1.Start();
            this.webBrowser1.Url = new Uri("http://127.0.0.1:"+port+"/index.php");
        }
       
        void MainFormFormClosed(object sender, FormClosedEventArgs e)
        {
            this.nanWebserver1.Stop();
        }
NANWebserver Klasse Downloads: 5112 times

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*