最近有個web的小項目,但公司的電腦沒法安裝IIS,因此就想本身來實現個Web server服務器,本來想了下,也就是socket處理http請求,因而就在博客園中搜索了「socket實現web server」,結果還真搜索到一些文章,因而從中找了幾個作參考,以下:javascript
C#中本身動手建立一個Web Server(非Socket實現)java
其餘的這裏就不一一列出了,感興趣的能夠本身搜索看看。web
因此我根據他們的代碼,而後本身在修改符合本身使用的狀況,初次版本就出來了,代碼以下:編程
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; namespace socket_webServer { class Program { static Socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //偵聽socket static string webRoot = @"C:\Users\jack\Desktop\"; static string defaultPage = "index.html,home.html"; static void Main(string[] args) { webRoot = @"C:\_jack\DevCode"; _socket.Bind(new IPEndPoint(IPAddress.Any, 8080)); _socket.Listen(100); _socket.BeginAccept(new AsyncCallback(OnAccept), _socket); //開始接收來自瀏覽器的http請求(實際上是socket鏈接請求) writeLog("Socket Web Server 已啓動監聽!" + Environment.NewLine + " 監聽端口:" + ((IPEndPoint)_socket.LocalEndPoint).Port); Console.ReadKey(); } /// <summary> /// 接受處理http的請求 /// </summary> /// <param name="ar"></param> static void OnAccept(IAsyncResult ar) { try { Socket socket = ar.AsyncState as Socket; Socket web_client = socket.EndAccept(ar); //接收到來自瀏覽器的代理socket //NO.1 並行處理http請求 socket.BeginAccept(new AsyncCallback(OnAccept), socket); //開始下一次http請求接收 (此行代碼放在NO.2處時,就是串行處理http請求,前一次處理過程會阻塞下一次請求處理) byte[] recv_Buffer = new byte[1024 * 640]; int recv_Count = web_client.Receive(recv_Buffer); //接收瀏覽器的請求數據 string recv_request = Encoding.UTF8.GetString(recv_Buffer, 0, recv_Count); writeLog("Data Request : " + recv_request); //將請求顯示到界面 //Resolve(recv_request, web_client); //解析、路由、處理 byte[] cont = pageHandle(RouteHandle(recv_request)); sendPageContent(cont, web_client); //NO.2 串行處理http請求 } catch (Exception ex) { writeLog("處理http請求時出現異常!" + Environment.NewLine + "\t" + ex.Message); } } static void sendPageContent(byte[] pageContent, Socket response) { string statusline = "HTTP/1.1 200 OK\r\n"; //狀態行 byte[] statusline_to_bytes = Encoding.UTF8.GetBytes(statusline); string content = "<html>" + "<head>" + "<title>socket webServer -- Login</title>" + "</head>" + "<body>" + "<div style=\"text-align:center\">" + "歡迎您!" + "" + ",今天是 " + DateTime.Now.ToLongDateString() + "</div>" + "</body>" + "</html>"; //內容 byte[] content_to_bytes = pageContent; string header = string.Format("Content-Type:text/html;charset=UTF-8\r\nContent-Length:{0}\r\n", content_to_bytes.Length); byte[] header_to_bytes = Encoding.UTF8.GetBytes(header); //應答頭 response.Send(statusline_to_bytes); //發送狀態行 response.Send(header_to_bytes); //發送應答頭 response.Send(new byte[] { (byte)'\r', (byte)'\n' }); //發送空行 response.Send(content_to_bytes); //發送正文(html) response.Close(); } /// <summary> /// /// </summary> /// <param name="request"></param> /// <returns></returns> static string RouteHandle(string request) { string retRoute = ""; string[] strs = request.Split(new string[] { "\r\n" }, StringSplitOptions.None); //以「換行」做爲切分標誌 if (strs.Length > 0) //解析出請求路徑、post傳遞的參數(get方式傳遞參數直接從url中解析) { string[] items = strs[0].Split(' '); //items[1]表示請求url中的路徑部分(不含主機部分) string pageName = items[1]; string post_data = strs[strs.Length - 1]; //最後一項 //Dictionary<string, string> dict = ParameterHandle(strs); retRoute = pageName + (post_data.Length > 0 ? "?" + post_data : ""); } return retRoute; } /// <summary> /// 按照HTTP協議格式,解析瀏覽器發送的請求字符串 /// </summary> /// <param name="strs"></param> /// <returns></returns> static Dictionary<string, string> ParameterHandle(string[] strs) { Dictionary<string, string> param = new Dictionary<string, string>(); if (strs.Length > 0) //解析出請求路徑、post傳遞的參數(get方式傳遞參數直接從url中解析) { if (strs.Contains("")) //包含空行 說明存在post數據 { string post_data = strs[strs.Length - 1]; //最後一項 if (post_data != "") { string[] post_datas = post_data.Split('&'); foreach (string s in post_datas) { param.Add(s.Split('=')[0], s.Split('=')[1]); } } } } return param; } static byte[] pageHandle(string pagePath) { byte[] pageContent = null; webRoot = webRoot.TrimEnd('/', '\\'); pagePath = pagePath.TrimEnd('/', '\\'); if (pagePath.Length==0) { foreach (string page in defaultPage.Split(',')) { if (System.IO.File.Exists(webRoot + page)) { pagePath = page; break; } } } if (System.IO.File.Exists(webRoot + pagePath)) pageContent = System.IO.File.ReadAllBytes(webRoot + pagePath); if (pageContent == null) { string content = notExistPage(); pageContent = Encoding.UTF8.GetBytes(content); } return pageContent; } static void writeLog(string msg) { Console.WriteLine(" " + msg); } static string notExistPage() { string cont = @"<!DOCTYPE HTML> <html> <head> <link rel='stylesheet' type='text/css' href='NewErrorPageTemplate.css' > <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'> <title>This page can’t be displayed</title> <script src='errorPageStrings.js' language='javascript' type='text/javascript'> </script> <script src='httpErrorPagesScripts.js' language='javascript' type='text/javascript'> </script> </head> <body onLoad='javascript:getInfo();'> <div id='contentContainer' class='mainContent'> <div id='mainTitle' class='title'>This page can’t be displayed</div> <div class='taskSection' id='taskSection'> <ul id='cantDisplayTasks' class='tasks'> <li id='task1-1'>Make sure the web address <span id='webpage' class='webpageURL'></span>is correct.</li> <li id='task1-2'>Look for the page with your search engine.</li> <li id='task1-3'>Refresh the page in a few minutes.</li> </ul> <ul id='notConnectedTasks' class='tasks' style='display:none'> <li id='task2-1'>Check that all network cables are plugged in.</li> <li id='task2-2'>Verify that airplane mode is turned off.</li> <li id='task2-3'>Make sure your wireless switch is turned on.</li> <li id='task2-4'>See if you can connect to mobile broadband.</li> <li id='task2-5'>Restart your router.</li> </ul> </div> <div><button id='diagnose' class='diagnoseButton' onclick='javascript:diagnoseConnectionAndRefresh(); return false;'>Fix connection problems</button></div> </div> </body> </html>"; return cont; } } }
這個web server的雛形就出來了,之後有須要的功能在慢慢往上添加吧瀏覽器
參考文章:服務器
Socket網絡編程--簡單Web服務器各章節傳送門網絡
Socket網絡編程--簡單Web服務器(1) http://www.cnblogs.com/wunaozai/p/3926033.html
Socket網絡編程--簡單Web服務器(2) http://www.cnblogs.com/wunaozai/p/3936295.html
Socket網絡編程--簡單Web服務器(3) http://www.cnblogs.com/wunaozai/p/3943952.html
Socket網絡編程--簡單Web服務器(4) http://www.cnblogs.com/wunaozai/p/3945218.html
Socket網絡編程--簡單Web服務器(5) http://www.cnblogs.com/wunaozai/p/3946486.html
Socket網絡編程--簡單Web服務器(6) http://www.cnblogs.com/wunaozai/p/3949324.html
源碼下載: http://files.cnblogs.com/wunaozai/WebServer.zipless