當輸入:127.0.0.1:5050 GET / HTTP/1.1 Accept: text/html, application/xhtml+xml, */* Accept-Language: zh-CN User-Agent: Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko Accept-Encoding: gzip, deflate Host: 127.0.0.1:5050 DNT: 1 Connection: Keep-Alive Cookie: s_pers=%20s_fid%3D5E4387B367FCC613-0DC7FD9C6D76C087%7C1453856077838%3B%20s_vs%3D1%7C1390785877860%3B%20s_nr%3D1390784077867-New%7C1422320077867%3B http://127.0.0.1:5050/index.html GET /index.html HTTP/1.1 Accept: text/html, application/xhtml+xml, */* Accept-Language: zh-CN User-Agent: Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko Accept-Encoding: gzip, deflate Host: 127.0.0.1:5050 DNT: 1 Connection: Keep-Alive Cookie: s_pers=%20s_fid%3D5E4387B367FCC613-0DC7FD9C6D76C087%7C1453856077838%3B%20s_vs%3D1%7C1390785877860%3B%20s_nr%3D1390784077867-New%7C1422320077867%3B 提交表單 POST / HTTP/1.1 Host: 127.0.0.1:5050 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:27.0) Gecko/20100101 Firefox/27.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Cookie: s_pers=%20s_fid%3D5E4387B367FCC613-0DC7FD9C6D76C087%7C1453856077838%3B%20s_vs%3D1%7C1390785877860%3B%20s_nr%3D1390784077867-New%7C1422320077867%3B Connection: keep-alive Content-Type: application/x-www-form-urlencoded Content-Length: 51 txtName=&txtClass=&txtPassword=&Submit=%CC%E1%BD%BB 提交表單 2 POST /CCC.asp HTTP/1.1 Host: 127.0.0.1:5050 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:27.0) Gecko/20100101 Firefox/27.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Cookie: s_pers=%20s_fid%3D5E4387B367FCC613-0DC7FD9C6D76C087%7C1453856077838%3B%20s_vs%3D1%7C1390785877860%3B%20s_nr%3D1390784077867-New%7C1422320077867%3B Connection: keep-alive Content-Type: application/x-www-form-urlencoded Content-Length: 68 txtName=name&txtClass=class&txtPassword=password&Submit=%CC%E1%BD%BB 提交表單3 POST /CCC.asp HTTP/1.1 Host: 127.0.0.1:5050 User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:27.0) Gecko/20100101 Firefox/27.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Cookie: s_pers=%20s_fid%3D5E4387B367FCC613-0DC7FD9C6D76C087%7C1453856077838%3B%20s_vs%3D1%7C1390785877860%3B%20s_nr%3D1390784077867-New%7C1422320077867%3B Connection: keep-alive Content-Type: application/x-www-form-urlencoded Content-Length: 93 txtName=%D5%C5%C8%FD&txtClass=%B8%DF%D2%BB%B6%FE%B0%E0&txtPassword=990749&Submit=%CC%E1%BD%BB
以上是 瀏覽器在瀏覽時發送給服務器的數據內容.在不一樣狀況下會有所不一樣.不過,通常數據量都很小.javascript
以上的 %D5%C5%C8%FD 其實是 urlencode 編碼方式:在程序開發的過程,須要對其進行解碼html
因爲IIS的不穩定性和難實施性(對操做系統太挑剔),一直想作個本身的輕量級Web服務器。java
今天終於抽出時間,藉助網絡上的實例,實現了本身的服務器,計劃之後在項目開發時嘗試取代IIS服務器。編程
在此把總體實現過程記錄下,以備後用。瀏覽器
技術實現原理:服務器
1.須要瞭解HTTP的工做原理網絡
2.須要瞭解基於C#的SOCKET編程,TcpListener類對象,監聽端口app
1、啓動VS2005,新建一個控制檯程序,命名:ConsoleApplication1ide
2、在添加CS文件,使名:MyWebServer.cs編碼
3、實現類MyWebServer,代碼以下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; namespace WindowsFormsApplication1 { class MyWebServer { private TcpListener myListener; private int port = 8899; // 選者任何閒置端口 //開始兼聽端口 //同時啓動一個兼聽進程 public MyWebServer() { try { //開始兼聽端口 myListener = new TcpListener(port); myListener.Start(); Console.WriteLine("Web Server Running... Press ^C to Stop..."); //同時啓動一個兼聽進程 ''StartListen'' Thread th = new Thread(new ThreadStart(StartListen)); th.Start(); } catch (Exception e) { Console.WriteLine("兼聽端口時發生錯誤 :" + e.ToString()); } } public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket mySocket) { String sBuffer = ""; if (sMIMEHeader.Length == 0) { sMIMEHeader = "text/html"; // 默認 text/html } sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n"; sBuffer = sBuffer + "Server: cx1193719-b\r\n"; sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n"; sBuffer = sBuffer + "Accept-Ranges: bytes\r\n"; sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n"; Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer); SendToBrowser(bSendData, ref mySocket); Console.WriteLine("Total Bytes : " + iTotBytes.ToString()); } public void SendToBrowser(String sData, ref Socket mySocket) { SendToBrowser(Encoding.ASCII.GetBytes(sData), ref mySocket); } public void SendToBrowser(Byte[] bSendData, ref Socket mySocket) { int numBytes = 0; try { if (mySocket.Connected) { if ((numBytes = mySocket.Send(bSendData, bSendData.Length, 0)) == -1) Console.WriteLine("Socket Error cannot Send Packet"); else { Console.WriteLine("No. of bytes send {0}", numBytes); } } else Console.WriteLine("鏈接失敗...."); } catch (Exception e) { Console.WriteLine("發生錯誤 : {0} ", e); } } public void StartListen() { int iStartPos = 0; String sRequest; String sDirName; String sRequestedFile; String sErrorMessage; String sLocalDir; /////////////////////////////////////注意設定你本身的虛擬目錄///////////////////////////////////// String sMyWebServerRoot = "C:\\Cassini\"; //設置你的虛擬目錄 ////////////////////////// String sFormattedMessage = ""; String sResponse = ""; while (true) { //接受新鏈接 Socket mySocket = myListener.AcceptSocket(); Console.WriteLine("Socket Type " + mySocket.SocketType); if (mySocket.Connected) { Console.WriteLine("\nClient Connected!!\n==================\nCLient IP {0}\n", mySocket.RemoteEndPoint); Byte[] bReceive = new Byte[1024]; int i = mySocket.Receive(bReceive, bReceive.Length, 0); //轉換成字符串類型 string sBuffer = Encoding.ASCII.GetString(bReceive); //只處理"get"請求類型 if (sBuffer.Substring(0, 3) != "GET") { Console.WriteLine("只處理get請求類型.."); mySocket.Close(); return; } // 查找 "HTTP" 的位置 iStartPos = sBuffer.IndexOf("HTTP", 1); string sHttpVersion = sBuffer.Substring(iStartPos, 8); // 獲得請求類型和文件目錄文件名 sRequest = sBuffer.Substring(0, iStartPos - 1); sRequest.Replace("\", "/"); //若是結尾不是文件名也不是以"/"結尾則加"/" if ((sRequest.IndexOf(".") < 1) && (!sRequest.EndsWith("/"))) { sRequest = sRequest + "/"; } //得帶請求文件名 iStartPos = sRequest.LastIndexOf("/") + 1; sRequestedFile = sRequest.Substring(iStartPos); //獲得請求文件目錄 sDirName = sRequest.Substring(sRequest.IndexOf("/"), sRequest.LastIndexOf("/") - 3); //獲取虛擬目錄物理路徑 sLocalDir = sMyWebServerRoot; Console.WriteLine("請求文件目錄 : " + sLocalDir); if (sLocalDir.Length == 0) { sErrorMessage = "<H2>Error!! Requested Directory does not exists</H2><Br>"; SendHeader(sHttpVersion, "", sErrorMessage.Length, " 404 Not Found", ref mySocket); SendToBrowser(sErrorMessage, ref mySocket); mySocket.Close(); continue; } if (sRequestedFile.Length == 0) { // 取得請求文件名 sRequestedFile = "index.html"; } ///////////////////////////////////////////////////////////////////// // 取得請求文件類型(設定爲text/html) ///////////////////////////////////////////////////////////////////// String sMimeType = "text/html"; string sPhysicalFilePath = sLocalDir + sRequestedFile; Console.WriteLine("請求文件: " + sPhysicalFilePath); if (File.Exists(sPhysicalFilePath) == false) { sErrorMessage = "<script language='javascript'>alert('你好呀,我不是IIS服務器!');</script>"; //SendHeader(sHttpVersion, "", sErrorMessage.Length, " 404 Not Found", ref mySocket); //SendToBrowser(sErrorMessage, ref mySocket); byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(sErrorMessage); SendHeader(sHttpVersion, sMimeType, bytes.Length, " 200 OK", ref mySocket); SendToBrowser(bytes, ref mySocket); //Console.WriteLine(sFormattedMessage); } else { int iTotBytes = 0; sResponse = ""; FileStream fs = new FileStream(sPhysicalFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader reader = new BinaryReader(fs); byte[] bytes = new byte[fs.Length]; int read; while ((read = reader.Read(bytes, 0, bytes.Length)) != 0) { sResponse = sResponse + Encoding.ASCII.GetString(bytes, 0, read); iTotBytes = iTotBytes + read; } reader.Close(); fs.Close(); SendHeader(sHttpVersion, sMimeType, iTotBytes, " 200 OK", ref mySocket); SendToBrowser(bytes, ref mySocket); //mySocket.Send(bytes, bytes.Length,0); } mySocket.Close(); } } } } }
4、編輯Program.cs,啓動監聽
static void Main(string[] args) { MyWebServer MWS = new MyWebServer(); Console.Read(); }