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: http://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: 2606 times
Tags: CGI, c, code.Mime, GUI-Designer, CSHARP, Perl, port, Allgemein, webserver, dynamisch, PHP, http, server