|
tp://www.quickviews.net/data/asp-net/" target="_blank" class="keylink">ASP.NET 应用程序域),而这两个(应用程序)域之间通过跨(应用程序)域的流对象引用来实现,使得在ASP.NET域中执行的结果可以通过web server域返回给请求者。
可以大致下图表达
执行ASP.NET的Web服务器端
WEB客户端
代码实现分析:
using System;
using System.Web ;
using System.Web.Hosting;
using System.IO;
using System.NET;
using System.NET.Sockets ;
using System.Text ;
using System.Threading ;
namespace MyIIS
{
class ASPHostServer
{
[STAThread]
static void Main(string[] args)
{
//创建并启动服务器
MyServer myserver=new MyServer(“/”, ”c:\\inetpub\\wwwroot\\myWeb”);
}
}
class MyServer //处理HTTP协议的服务器类
{
private ASPDOTNETHost ASPnetHost; //ASP.NET host的实例
private TcpListener mytcp; //Web监听套接字
bool bSvcRunning=true; //服务是否运行指示
FileStream fs; //处理http请求的普通文本要求
public MyServer(string virtualDir ,vstring realPath)
{//在构造函数中启动web监听服务
try
{
mytcp=new TcpListener(8001);
mytcp.Start(); //启动在8001端口的监听
Console.WriteLine("服务启动...");
//利用CreateApplicationHost方法建立一个独立的应用程序域执行ASP.NET程序
ASPnetHost = ( ASPDOTNETHost )ApplicationHost.CreateApplicationHost
( typeof( ASPDOTNETHost ) , virtualDir , realPath);
Thread t=new Thread(new ThreadStart(MainSvcThread));
t.Start(); //服务线程启动 负责处理每一个客户端的请求
}
catch(NullReferenceException)
{
Console.WriteLine("NullReferenceException throwed!") ;
}
}
public void MainSvcThread() //ASP.NET Host的web服务器的主要服务线程
{
int s=0;
string strRequest; //请求信息
string strDir; //请求的目录
string strRequestFile; //请求的文件名
string strErr=""; //错误信息
string strRealDir; //实际目录
string strWebRoot=rpath; //应用根目录
string strRealFile=""; //正在请求的文件的磁盘路径
string strResponse=""; //回应响应缓冲区
string strMsg=""; //格式化响应信息
byte[] bs; //输出字节缓冲区
while(bSvcRunning)
{
Socket sck=mytcp.AcceptSocket(); //每个请求到来
if(sck.Connected)
{
Console.WriteLine("Client {0} connected!",sck.RemoteEndPoint);
byte[] bRecv=new byte[1024]; //缓冲区
int l=sck.Receive(bRecv,bRecv.Length,0);
string strBuf=Encoding.Default.GetString(bRecv); //转换成字符串,便于分析
s=strBuf.IndexOf("HTTP",1);
string httpver=strBuf.Substring(s,8); // HTTP/1.1 之类的
strRequest=strBuf.Substring(0,s-1);
strRequest.Replace("\\","/");
if((strRequest.IndexOf(".")<1) && (!strRequest.EndsWith("/")))
{
strRequest = "/";
}
s=strRequest.LastIndexOf("/") 1;
strRequestFile = strRequest.Substring(s); strDir=strRequest.Substring(strRequest.IndexOf("/"),strRequest.LastIndexOf("/")-3); //取得访问的URL
if(strDir=="/")
{
strRealDir=strWebRoot;
}
else
{
strDir=strDir.Replace("/","\\");
strRealDir=strWebRoot strDir;
}
Console.WriteLine("Client request dir: {0}" , strRealDir);
if(strRequestFile.Length==0)
{
strRequestFile="default.htm"; //缺省文档
}
int iTotlaBytes=0; //总计需要输出的字节
strResponse=""; //输出内容
strRealFile = strRealDir "\\" strRequestFile;
if(strRealFile.EndsWith(".ASPx")) //这里有Bug!!
{
string output="";
//注意我下面的语句们给host对象ProcessRequest方法传递了一个ref类型的参数,
//ASPnetHost会从ASP.NET的执行应用程序域执行一个请求后返回流给当前web server所在的域,这实际上发生了一个域间的调用
ASPnetHost.ProcessRequest (strRequestFile, ref output);//转换成字节流
bs=System.Text.Encoding.Default.GetBytes (output);
iTotlaBytes=bs.Length ; //调用套接字将执行结果返回
WriteHeader(httpver,"text/html",iTotlaBytes,"200 OK",ref sck);
FlushBuf(bs,ref sck);
}
else
{try
{
fs=new FileStream( strRealFile,FileMode.Open,FileAccess.Read,FileShare.Read );
BinaryReader reader=new BinaryReader(fs); //读取
bs=new byte[fs.Length ];
int rb;
while((rb=reader.Read(bs,0,bs.Length ))!=0)
{
strResponse =strResponse Encoding.Default.GetString(bs,0,rb);
iTotlaBytes =iTotlaBytes rb;
}
reader.Close();
fs.Close();
WriteHeader(httpver,"text/html",iTotlaBytes,"200 OK",ref sck);
FlushBuf(bs,ref sck);
}
catch(System.IO.FileNotFoundException )
{//假设找不到文件,报告404 WriteHeader(httpver,"text/html",iTotlaBytes,"404 OK",ref sck);
}
}
}
上一页 [1] [2] [3] [4] [5] 下一页
|