基于C#动手实现网络服务器Web Server

2019-12-30 18:15:43刘景俊

这样就可以提供基本的网页访问了,经过测试,使用Bootstrap,Pure等前端框架的网页都可以完美访问,性能方面一般般。(在QFramework的封装中我做了一点性能优化,有一点提升)我觉得要在性能方面做提升还是要在多线程处理这方面做优化,由于篇幅关系,就不把多线程版本的代码贴出来了。

接下来我们还要实现服务器的PHP支持。

首先定义两个字段。


/// <summary>
/// 是否开启PHP功能
/// </summary>
public bool PHP_CGI_Enabled = true;

/// <summary>
/// PHP执行文件路径
/// </summary>
public string PHP_CGI_Path = "php-cgi";
接下来在网页服务的核心代码里做PHP支持的处理。

//PHP处理
string phpCgiOutput = "";
Action phpProc = new Action(() =>
{
  try
  {
    string argStr = "";

    if (request.HttpMethod == "GET")
    {
      if (rawUrl.IndexOf('?') > -1)
        argStr = rawUrl.Substring(rawUrl.IndexOf('?'));
    }
    else if (request.HttpMethod == "POST")
    {
      using (StreamReader reader = new StreamReader(request.InputStream))
      {
        argStr = reader.ReadToEnd();
      }
    }

    Process p = new Process();
    p.StartInfo.CreateNoWindow = false; //不显示窗口
    p.StartInfo.RedirectStandardOutput = true; //重定向输出
    p.StartInfo.RedirectStandardInput = false; //重定向输入
    p.StartInfo.UseShellExecute = false; //是否指定操作系统外壳进程启动程序
    p.StartInfo.FileName = PHP_CGI_Path;
    p.StartInfo.Arguments = string.Format("-q -f {0} {1}", fileName, argStr);
    p.Start();

    StreamReader sr = p.StandardOutput;
    while (!sr.EndOfStream)
    {
      phpCgiOutput += sr.ReadLine() + Environment.NewLine;
    }

    responseByte = sr.CurrentEncoding.GetBytes(phpCgiOutput);
  }
  catch (Exception ex)
  {
    Qdb.Error(ex.Message, QDebugErrorType.Error, "onWebResponse->phpProc");
    response.StatusCode = (int)HttpStatusCode.InternalServerError;
  }
});

if (fileExt == "php" && PHP_CGI_Enabled)
{
  phpProc();
}
else
{
  if (!File.Exists(fileName))
  {
    responseByte = Encoding.UTF8.GetBytes("404 Not Found!");
    response.StatusCode = (int)HttpStatusCode.NotFound;
  }
  else
  {
    try
    {
      responseByte = File.ReadAllBytes(fileName);
      response.StatusCode = (int)HttpStatusCode.OK;
    }
    catch (Exception ex)
    {
      Qdb.Error(ex.Message, QDebugErrorType.Error, "onWebResponse");
      response.StatusCode = (int)HttpStatusCode.InternalServerError;
    }
  }
}

这样就实现了基于PHP-CGI的PHP支持了,经过测试,基本的php页面都可以支持,但是需要使用curl和xml这类扩展的暂时还没办法。需要做更多的工作。

接下来我会给服务器做一个GUI界面,供大家测试。

同时也会把QFramework框架发布,有兴趣的可以使用基于QFramework的服务器封装。