下面是我个人对网站开发框架的一点理解,下面做出了大概的模型,实现了基本的功能,下面也有所有的代码可以提供参考;
一开始学的时候不要把网站想的太复杂了,把网站的流程和大概的原理框架搞清楚,在通过代码大概的实现出来,这样以后面对网站开发的时候就会有一个具体的模型。
网站是一种通讯工具,就像布告栏一样,人们可以通过网站来发布自己想要公开的资讯,或者利用网站来提供相关的网络服务。人们可以通过网页浏览器来访问网站,获取自己需要的资讯或者享受网络服务。
其实网站开发无非就是接收到客户端发送过来的请求页面,然后对报文进行有必要的处理,在这个过程可以用事件管道处理来提高扩展性,在重新组装成新的报文,把它按照指定的报文格式发送回客户端去,而浏览器就可以得到响应,接收到想要的数据页面,同时,网站服务将关闭,等有新的请求的时候在开启服务。这个是客户端请求网站数据时的大概过程。
代码都有详细的注释,我就不多列外写了。
当然,这只是我个人的一点理解,我也是初学者,所以仅供参考,有不对的地方也可以指出。
forMyServer网站主页
class="code_img_closed" src="/Upload/Images/2013120811/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('a81ab527-38fc-4f67-9379-5f8f480e46e7',event)" src="/Upload/Images/2013120811/2B1B950FA3DF188F.gif" alt="" />1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.IO; 7 using System.Linq; 8 using System.Net; 9 using System.Net.Sockets; 10 using System.Runtime.Serialization.Formatters.Binary; 11 using System.Text; 12 using System.Threading; 13 using System.Threading.Tasks; 14 using System.Windows.Forms; 15 16 namespace MyServer 17 { 18 public partial class forMyServer : Form 19 { 20 public forMyServer() 21 { 22 InitializeComponent(); 23 } 24 private Sites sites = null;//站点实体 25 BinaryFormatter formatter = null;//序列化 26 private void menuAdd_Click(object sender, EventArgs e) 27 { 28 forAddServer f = new forAddServer(); 29 f.SiteEvent += ServerSite;//添加事件 30 f.ShowDialog(); 31 } 32 private void ServerSite(Site s)//事件处理 33 { 34 treeView1.Nodes.Clear(); 35 sites.Add(s); 36 string fileName = "a.dat";//序列化文件名(随便取的) 37 string path = Application.ExecutablePath;//获取路劲 38 path = path.Substring(0, path.LastIndexOf('\\')); 39 fileName = path + "\\" + fileName;//带路径的文件名 40 using (FileStream fs = new FileStream(fileName, FileMode.Create)) 41 { 42 formatter = new BinaryFormatter(); 43 formatter.Serialize(fs, sites);//序列化对象 44 } 45 TreeNode root = new TreeNode("所有站点"); 46 treeView1.Nodes.Add(root); 47 foreach(Site site in sites)//添加站点到属性控件 48 { 49 TreeNode node = new TreeNode(site.SiteName); 50 node.Tag = site; 51 root.Nodes.Add(node); 52 } 53 } 54 55 private void forMyServer_Load(object sender, EventArgs e) 56 { 57 string fileName = "a.dat"; 58 string path = Application.ExecutablePath; 59 path = path.Substring(0, path.LastIndexOf('\\')); 60 fileName = path + "\\" + fileName; 61 sites = new Sites(); 62 if (!File.Exists(fileName)) 63 File.Create(fileName); 64 using (FileStream fs = new FileStream(fileName, FileMode.Open)) 65 { 66 if (sites != null) 67 { 68 formatter = new BinaryFormatter(); 69 sites = formatter.Deserialize(fs) as Sites; 70 TreeNode root = new TreeNode("所有站点"); 71 treeView1.Nodes.Add(root); 72 foreach (Site s in sites) 73 { 74 TreeNode node = new TreeNode(s.SiteName); 75 node.Tag = s; 76 root.Nodes.Add(node); 77 } 78 } 79 } 80 } 81 82 private void menuStart_Click(object sender, EventArgs e) 83 { 84 //取出树形控件中选中的站点 85 if (treeView1.SelectedNode != null && treeView1.SelectedNode.Level > 0) 86 { 87 //取出用户选中的站点对象 88 Site currSite = treeView1.SelectedNode.Tag as Site; 89 //站点没有开启就开启 90 if (!currSite.IsStart) 91 { 92 ParameterizedThreadStart p = new ParameterizedThreadStart(ListenSocket); 93 Thread t1 = new Thread(p); 94 t1.Start(currSite);//开启一个线程 95 } 96 } 97 } 98 public void ListenSocket(object currSite) //监听Ip地址 99 { 100 Site s = currSite as Site; 101 Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 102 EndPoint endPoint = new IPEndPoint(IPAddress.Any, 8080); 103 server.Bind(endPoint); 104 server.Listen(1000);//开启监听 105 s.IsStart = true;//表示以开启此站点,不用开启 106 HttpContext h = new HttpContext(); 107 h.SitePath = s.Path; 108 while(true) 109 { 110 Socket client = server.Accept();//接收用户实例 111 h.TxSocket = client; 112 Thread t = new Thread(Process); 113 t.Start(h); 114 } 115 } 116 public void Process(object c)//发送页面回去的处理流程 117 { 118 HttpContext h = c as HttpContext; 119 Socket client = h.TxSocket; 120 byte[] b = new byte[1024]; 121 int length = client.Receive(b); 122 string str = Encoding.UTF8.GetString(b, 0, length);//得到报文 123 h.Info = new HttpInfo(str);//拆分报文 124 h.Response = new HttpResponse();//组装新的报文 125 HttpAllContext allContext = new HttpAllContext();//所有信息 126 allContext.GeneratePages(h); 127 client.Send(h.Response.b);//发送数据 128 client.Close();//关闭服务 129 } 130 131 private void 退出服务ToolStripMenuItem_Click(object sender, EventArgs e) 132 { 133 //client.Close();//关闭服务 134 Application.Exit(); 135 } 136 }View Code
forAddServer添加网站
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 11 namespace MyServer 12 { 13 public partial class forAddServer : Form 14 { 15 public forAddServer() 16 { 17 InitializeComponent(); 18 } 19 public delegate void SiteDelegate(Site s); 20 public event SiteDelegate SiteEvent; 21 private void btnBrowse_Click(object sender, EventArgs e) 22 { 23 FolderBrowserDialog open = new FolderBrowserDialog(); 24 DialogResult result = open.ShowDialog(); 25 if(result == DialogResult.OK)//获得站点路径 26 { 27 txtDirectory.Text = open.SelectedPath; 28 } 29 } 30 31 private bool Valid(out string info) //判断格式 32 { 33 //此处没有做特殊处理,所以我在次提醒读者们 34 bool flag = true; 35 if (txtName.Text == "" || txtIP.Text == "" || txtPort.Text == "") 36 { 37 flag = false; 38 info = "不能为空"; 39 } 40 else 41 info = "添加成功!"; 42 return flag; 43 } 44 45 private void btnOK_Click(object sender, EventArgs e) 46 { 47 string info; 48 if (Valid(out info)) 49 MessageBox.Show(info); 50 else 51 { 52 MessageBox.Show(info); 53 return; 54 } 55 Site s = new Site() { 56 SiteName=txtName.Text, 57 IpAddress=txtIP.Text, 58 Path=txtDirectory.Text, 59 Port=txtPort.Text, 60 IsStart=false 61 }; 62 SiteEvent(s); 63 } 64 65 private void btnCancel_Click(object sender, EventArgs e) 66 { 67 this.Close(); 68 } 69 } 70 }View Code
Site站点类
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace MyServer 8 { 9 [Serializable] 10 public class Site//站点 11 { 12 public string SiteName { get;set; } 13 public string IpAddress { get; set; } 14 public string Port { get; set; } 15 public string Path { get; set; } 16 [NonSerialized] 17 public bool IsStart; 18 } 19 }View Code
Sites站点集合
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace MyServer 8 { 9 [Serializable] 10 public class Sites : List<Site> 11 { 12 //public List<Site> sites = new List<Site>(); 13 //public Sites(Site s) 14 //{ 15 // sites.Add(s); 16 //} 17 } 18 }View Code
HttpInfo拆分报文
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace MyServer 8 { 9 public class HttpInfo 10 { 11 public string Method { get; set; }//GET POST 12 public string Url { get; set; } //请求地址URL 13 public string Protocol { get; set; }//使用的协议 14 public string Other { get; set; }//其它 15 16 public HttpInfo(string str) 17 { 18 string[] keys = str.Split(new string[] { "\r\n" }, StringSplitOptions.None); 19 string[] rows = keys[0].Split(' ');//GET /1.html HTTP/1.1 20 21 this.Method = rows[0];//获取Get/Post方法 22 this.Url = rows[1].Substring(1); 23 this.Protocol = rows[2]; 24 25 this.Other = str; 26 } 27 } 28 }View Code
Response反应的内容
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace MyServer 8 { 9 public class HttpResponse 10 { 11 public byte[] b = null; 12 public string CreateOutHtml(string html) 13 { 14 StringBuilder sb = new StringBuilder(); 15 sb.Append("HTTP/1.1 200 OK\r\n"); 16 sb.Append("Content-Type: text/html\r\n"); 17 sb.Append("Last-Modified: Mon, 02 Dec 2013 12:21:06 GMT\r\n"); 18 sb.Append("Accept-Ranges: bytes\r\n"); 19 sb.Append("Server: Microsoft-IIS/7.5\r\n"); 20 sb.Append("Content-Length: 426\r\n\r\n"); 21 22 sb.Append(html);//连接上报文头部 23 24 return html; 25 } 26 } 27 }View Code
HttpContext内容实体
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net.Sockets; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace MyServer 9 { 10 public class HttpContext 11 { 12 public string SitePath { get; set; }//路径地址 13 public Socket TxSocket { get; set; } 14 public HttpResponse Response { get; set; }//全部报文 15 public HttpInfo Info { get; set; }//拆分报文获得想要的信息 16 } 17 }View Code
HttpAllContext请求事件处理
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using System.Windows.Forms; 8 9 namespace MyServer 10 { 11 public class HttpAllContext 12 { 13 public delegate void ValidUserDelegate(HttpContext context); 14 public delegate void LoadCache(HttpContext context); 15 public delegate void LoadStatus(HttpContext context); 16 public delegate void GeneratePage(HttpContext context); 17 public delegate void WriteStatus(HttpContext context); 18 19 //生成页面 20 public event ValidUserDelegate ValidUserHandler;//报文头 21 public event LoadCache LoadCacheHandler; 22 public event LoadStatus LoadStatusHandler; 23 public event GeneratePage GeneratePageHandler; //生成页面 24 public event WriteStatus WriteStatusHandler;//状态 25 26 //获取请求的参数:从context.Request 27 //生成的页面:context.Response 28 //支持客户自定义处理方式,扩展性-----事件 “管道技术” 29 public void ProcessPage(HttpContext context) 30 { 31 if (ValidUserHandler != null) ValidUserHandler(context); 32 if (LoadCacheHandler != null) LoadCacheHandler(context); 33 if (LoadStatusHandler != null) LoadStatusHandler(context); 34 if (GeneratePageHandler != null) GeneratePageHandler(context); 35 if (WriteStatusHandler != null) WriteStatusHandler(context); 36 } 37 38 public void GeneratePages(HttpContext context)//出错 39 { 40 HttpInfo httpInfo = context.Info;//拆分报文类获得地址等 41 //从报文中拆出请求的带路径html文件名 42 string htmlFileName = context.SitePath + "\\" + httpInfo.Url; 43 //如果有这个请求的文件就往下执行 44 if (File.Exists(htmlFileName)) 45 { 46 //读取文件中的所有内容 47 string html = File.ReadAllText(htmlFileName); 48 //重新组装报文 49 HttpResponse httpResponse = new HttpResponse(); 50 html = httpResponse.CreateOutHtml(html); 51 byte[] bb = Encoding.UTF8.GetBytes(html); 52 context.Response.b = bb; 53 MessageBox.Show("请求成功!"); 54 } 55 else 56 { 57 //错误处理。。。 58 //string html = "404错误!"; 59 /context.Response.b = Encoding.UTF8.GetBytes(html); 60 M/essageBox.Show("请求失败!"); 61 } 62 } 63 } 64 }View Code