Web服务器具体开发流程
下面是我个人对Web服务器开发流程的一点理解,下面做出了大概的模型,实现了基本的功能,下面也有所有的代码可以提供参考;
一开始学的时候不要把网站想的太复杂了,把网站的流程和大概的原理框架搞清楚,在通过代码大概的实现出来,这样以后面对网站开发的时候就会有一个具体的模型。
网站是一种通讯工具,就像布告栏一样,人们可以通过网站来发布自己想要公开的资讯,或者利用网站来提供相关的网络服务。人们可以通过网页浏览器来访问网站,获取自己需要的资讯或者享受网络服务。
其实Web服务器网站开发无非就是接收到客户端发送过来的请求页面,然后对报文进行有必要的处理,在这个过程可以用事件管道处理来提高扩展性,在重新组装成新的报文,把它按照指定的报文格式发送回客户端去,而浏览器就可以得到响应,接收到想要的数据页面,同时,网站服务将关闭,等有新的请求的时候在开启服务。这个是客户端请求网站数据时的大概过程。
代码都有详细的注释,我就不多列外写了。
当然,这只是我个人的一点理解,我也是初学者,所以仅供参考,有不对的地方也可以指出。
forMyServer网站主页
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyServer
{
public partial class forMyServer : Form
{
public forMyServer()
{
InitializeComponent();
}
private Sites sites = null;//站点实体
BinaryFormatter formatter = null;//序列化
private void menuAdd_Click(object sender, EventArgs e)
{
forAddServer f = new forAddServer();
f.SiteEvent += ServerSite;//添加事件
f.ShowDialog();
}
private void ServerSite(Site s)//事件处理
{
treeView1.Nodes.Clear();
sites.Add(s);
string fileName = "a.dat";//序列化文件名(随便取的)
string path = Application.ExecutablePath;//获取路劲
path = path.Substring(, path.LastIndexOf('\\'));
fileName = path + "\\" + fileName;//带路径的文件名
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
formatter = new BinaryFormatter();
formatter.Serialize(fs, sites);//序列化对象
}
TreeNode root = new TreeNode("所有站点");
treeView1.Nodes.Add(root);
foreach(Site site in sites)//添加站点到属性控件
{
TreeNode node = new TreeNode(site.SiteName);
node.Tag = site;
root.Nodes.Add(node);
}
}
private void forMyServer_Load(object sender, EventArgs e)
{
string fileName = "a.dat";
string path = Application.ExecutablePath;
path = path.Substring(, path.LastIndexOf('\\'));
fileName = path + "\\" + fileName;
sites = new Sites();
if (!File.Exists(fileName))
File.Create(fileName);
using (FileStream fs = new FileStream(fileName, FileMode.Open))
{
if (sites != null)
{
formatter = new BinaryFormatter();
sites = formatter.Deserialize(fs) as Sites;
TreeNode root = new TreeNode("所有站点");
treeView1.Nodes.Add(root);
foreach (Site s in sites)
{
TreeNode node = new TreeNode(s.SiteName);
node.Tag = s;
root.Nodes.Add(node);
}
}
}
}
private void menuStart_Click(object sender, EventArgs e)
{
//取出树形控件中选中的站点
)
{
//取出用户选中的站点对象
Site currSite = treeView1.SelectedNode.Tag as Site;
//站点没有开启就开启
if (!currSite.IsStart)
{
ParameterizedThreadStart p = new ParameterizedThreadStart(ListenSocket);
Thread t1 = new Thread(p);
t1.Start(currSite);//开启一个线程
}
}
}
public void ListenSocket(object currSite) //监听Ip地址
{
Site s = currSite as Site;
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint endPoint = );
server.Bind(endPoint);
server.Listen();//开启监听
s.IsStart = true;//表示以开启此站点,不用开启
HttpContext h = new HttpContext();
h.SitePath = s.Path;
while(true)
{
Socket client = server.Accept();//接收用户实例
h.TxSocket = client;
Thread t = new Thread(Process);
t.Start(h);
}
}
public void Process(object c)//发送页面回去的处理流程
{
HttpContext h = c as HttpContext;
Socket client = h.TxSocket;
];
int length = client.Receive(b);
, length);//得到报文
h.Info = new HttpInfo(str);//拆分报文
h.Response = new HttpResponse();//组装新的报文
HttpAllContext allContext = new HttpAllContext();//所有信息
h.Context = allContext;
HttpFactory.CreateHandler(h);
allContext.ProcessPage(h);//触发事件
client.Send(h.Response.b);//发送数据
client.Close();//关闭服务
}
private void 退出服务ToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}

forAddServer添加网站
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyServer
{
public partial class forAddServer : Form
{
public forAddServer()
{
InitializeComponent();
}
public delegate void SiteDelegate(Site s);
public event SiteDelegate SiteEvent;
private void btnBrowse_Click(object sender, EventArgs e)
{
FolderBrowserDialog open = new FolderBrowserDialog();
DialogResult result = open.ShowDialog();
if(result == DialogResult.OK)//获得站点路径
{
txtDirectory.Text = open.SelectedPath;
}
}
private bool Valid(out string info) //判断格式
{
//此处没有做特殊处理,所以我在次提醒读者们
bool flag = true;
if (txtName.Text == "" || txtIP.Text == "" || txtPort.Text == "")
{
flag = false;
info = "不能为空";
}
else
info = "添加成功!";
return flag;
}
private void btnOK_Click(object sender, EventArgs e)
{
string info;
if (Valid(out info))
MessageBox.Show(info);
else
{
MessageBox.Show(info);
return;
}
Site s = new Site() {
SiteName=txtName.Text,
IpAddress=txtIP.Text,
Path=txtDirectory.Text,
Port=txtPort.Text,
IsStart=false
};
SiteEvent(s);
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
Site站点类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyServer
{
[Serializable]
public class Site//站点
{
public string SiteName { get;set; }
public string IpAddress { get; set; }
public string Port { get; set; }
public string Path { get; set; }
[NonSerialized]
public bool IsStart;
}
}
Sites站点集合
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyServer
{
[Serializable]
public class Sites : List<Site>
{
//public List<Site> sites = new List<Site>();
//public Sites(Site s)
//{
// sites.Add(s);
//}
}
}
HttpInfo拆分报文
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyServer
{
public class HttpInfo
{
public string Method { get; set; }//GET POST
public string Url { get; set; } //请求地址URL
public string Protocol { get; set; }//使用的协议
public string Other { get; set; }//其它
public HttpInfo(string str)
{
string[] keys = str.Split(new string[] { "\r\n" }, StringSplitOptions.None);
].Split(' ');//GET /1.html HTTP/1.1
];//获取Get/Post方法
].Substring();
];
this.Other = str;
}
}
}
Response反应的内容
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyServer
{
public class HttpResponse
{
public byte[] b = null;
public string CreateOutHtml(string html)
{
StringBuilder sb = new StringBuilder();
sb.Append("HTTP/1.1 200 OK\r\n");
sb.Append("Content-Type: text/html\r\n");
sb.Append("Last-Modified: Mon, 02 Dec 2013 12:21:06 GMT\r\n");
sb.Append("Accept-Ranges: bytes\r\n");
sb.Append("Server: Microsoft-IIS/7.5\r\n");
sb.Append("Content-Length: 426\r\n\r\n");
sb.Append(html);//连接上报文头部
return html;
}
}
}
HttpContext内容实体
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace MyServer
{
public class HttpContext
{
public string SitePath { get; set; }//路径地址
public Socket TxSocket { get; set; }
public HttpResponse Response { get; set; }//全部报文
public HttpInfo Info { get; set; }//拆分报文获得想要的信息
public HttpAllContext Context { get; set; }
}
}
HttpAllContext请求事件处理
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyServer
{
public class HttpAllContext
{
public delegate void ValidUserDelegate(HttpContext context);
public delegate void LoadCache(HttpContext context);
public delegate void LoadStatus(HttpContext context);
public delegate void GeneratePage(HttpContext context);
public delegate void WriteStatus(HttpContext context);
//生成页面
public event ValidUserDelegate ValidUserHandler;//报文头
public event LoadCache LoadCacheHandler;
public event LoadStatus LoadStatusHandler;
public event GeneratePage GeneratePageHandler; //生成页面
public event WriteStatus WriteStatusHandler;//状态
//获取请求的参数:从context.Request
//生成的页面:context.Response
//支持客户自定义处理方式,扩展性-----事件 “管道技术”
public void ProcessPage(HttpContext context)
{
if (ValidUserHandler != null) ValidUserHandler(context);
if (LoadCacheHandler != null) LoadCacheHandler(context);
if (LoadStatusHandler != null) LoadStatusHandler(context);
if (GeneratePageHandler != null) GeneratePageHandler(context);
if (WriteStatusHandler != null) WriteStatusHandler(context);
}
}
}

HttpFactory工厂类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyServer
{
public abstract class HttpFactory
{
public static void CreateHandler(HttpContext con)
{
IHttpHead head = null;
//获取该文件的后缀类型 xxx.html
string extName = con.Info.Url.Substring(con.Info.Url.LastIndexOf('.'));
switch (extName)
{
case ".html": head = new HtmlHead(); break;
//case ".js": head = new JsHead(); break;
}
//添加事件
con.Context.GeneratePageHandler += head.Process;
}
}
}
IHttpHead//定义一个借口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyServer
{
public interface IHttpHead
{
void Process(HttpContext con);
}
}
HtmlHead子类
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyServer
{
public class HtmlHead : IHttpHead
{
public void Process(HttpContext context)
{
HttpInfo httpInfo = context.Info;//拆分报文类获得地址等
//从报文中拆出请求的带路径html文件名
string htmlFileName = context.SitePath + "\\" + httpInfo.Url;
//如果有这个请求的文件就往下执行
if (File.Exists(htmlFileName))
{
//读取文件中的所有内容
string html = File.ReadAllText(htmlFileName);
//重新组装报文
html = context.Response.CreateOutHtml(html);
byte[] bb = Encoding.UTF8.GetBytes(html);
context.Response.b = bb;
MessageBox.Show("请求成功!");
}
else
{
}
}
}
}
Web服务器具体开发流程的更多相关文章
- 一个WEB应用的开发流程
转载:http://www.51testing.com/html/56/n-3721856.html 先说项目开发过程中团队人员的分工协作. 一.人员安排 毕业至今的大部分项目都是独立完成,虽然也有和 ...
- 1.一个WEB应用的开发流程
先说项目开发过程中团队人员的分工协作. 一.人员安排 毕业至今的大部分项目都是独立完成,虽然也有和其他同事协作的时候,但自认为对团队协作的了解和认知都还有所欠缺.很清楚团队协作的重要性,但尚未有很好的 ...
- 前端工程化的的理解,浅谈web工程化的开发流程
1. 什么是前端工程化 自有前端工程师这个称谓以来,前端的发展可谓是日新月异.相比较已经非常成熟的其他领域,前端虽是后起之秀,但其野蛮生长是其他领域不能比的.虽然前端技术飞快发展,但是前端整体的工程生 ...
- ASP.NET协作应用集成到trsids身份验证服务器的开发流程
开发Actor协同模块: (参考TRSIDS4.0 协作应用集成手册[asp.net]) ASP.Net协作应用集成到IDS之前,需要开发Actor类实现协作应用回调接口中定义的本地登录.退出.用户信 ...
- C# web server的开发流程
http://blog.csdn.net/h0322/article/details/4776819
- flask实战-留言板-Web程序开发流程
Web程序开发流程 在实际的开发中,一个Web程序的开发过程要设计多个角色,比如客户(提出需求).项目经理(决定需求的实现方式).开发者(实现需求)等,在这里我们假设自己是一个人全职开发.一般来说一个 ...
- Python之HTTP静态Web服务器开发
众所周知,Http协议是基于Tcp协议的基础上产生的浏览器到服务器的通信协议 ,其根本原理也是通过socket进行通信. 使用HTTP协议通信,需要注意其返回的响应报文格式不能有任何问题. 响应报文, ...
- 打造一款属于自己的web服务器——从简单开始
距离开篇已经过了很久,期间完善了一下之前的版本,目前已经能够完好运行,基本上该有的功能都有了,此外将原来的测试程序改为示例项目,新项目只需按照示例项目结构实现controller和view即可,详情见 ...
- 嵌入式web服务器BOA的移植及应用
嵌入式web服务器子系统 一.嵌入式web服务器的控制流程 如下图所示,嵌入式web服务器可实现通过网络远程控制嵌入式开发板,便捷实用. 控制流程:浏览器 --->>>嵌入式开发板 ...
随机推荐
- 170多个Ionic Framework学习资源(转载)
在Ionic官网找到的学习资源:http://blog.ionic.io/learning-ionic-in-your-living-room/ 网上的文章比较多,但是很多时候我们很难找到自己需要的. ...
- [SDK2.2]Windows Azure Virtual Network (3) 创建AD Server并添加至Virtual Network
<Windows Azure Platform 系列文章目录> 在之前的文章中,笔者已经向大家介绍了如何创建一个简单的Azure Virtual Network. 本章我将创建一台域服务器 ...
- [SDK2.2]Windows Azure Virtual Network (4) 创建Web Server 001并添加至Virtual Network
<Windows Azure Platform 系列文章目录> 在上一章内容中,笔者已经介绍了以下两个内容: 1.创建Virtual Network,并且设置了IP range 2.创建A ...
- Android Studio快捷键每日一练(4)
原文地址:http://www.developerphil.com/android-studio-tips-of-the-day-roundup-4/ 33.分析数据流到当前位置 苹果/Windows ...
- SQL Server获取下一个编码字符串的实现方案分割和进位
我在前一种解决方案SQL Server获取下一个编码字符实现和后一种解决方案SQL Server获取下一个编码字符实现继续重构与增强两篇博文中均提供了一种解决编码的方案,考虑良久对比以上两种方 ...
- 使用Python将Excel中的数据导入到MySQL
使用Python将Excel中的数据导入到MySQL 工具 Python 2.7 xlrd MySQLdb 安装 Python 对于不同的系统安装方式不同,Windows平台有exe安装包,Ubunt ...
- 30天C#基础巩固----Lambda表达式
这几天有点不在状态,每一次自己很想认真的学习,写点东西的时候都会被各种小事情耽误,执行力太差.所以自己反思了下最近的学习情况,对于基础的知识,可以从书中和视频中学习到,自己还是需要注意下关于 ...
- 原生JS 获取浏览器、窗口、元素等尺寸的方法及注意事项
一.通过浏览器获得屏幕的尺寸 screen.width screen.height screen.availHeight //获取去除状态栏后的屏幕高度 screen.availWidth //获取去 ...
- 在Gridview如何进行每行单元格比较
有在论坛上看到一个问题,就是在Gridview控件中,需要对几个列的数值进行比较,原问题如下: 先在数据库中准备数据: CREATE TABLE [dbo].[RecordTime] ( Id ,) ...
- 广义表 Head Tail
head:取非空广义表的第一个元素 tail:取非空广义表除第一个元素外剩余元素构成的广义表 L=((x,y,z),a,(u,t,w)) head(L)为(x,y,z) head(head(L))为x ...