• 模拟服务器


    一、使用窗体程序写一个简单的UI

     后台代码

     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.Net;
     8 using System.Net.Sockets;
     9 using System.Text;
    10 using System.Threading;
    11 using System.Threading.Tasks;
    12 using System.Windows.Forms;
    13 
    14 namespace MyWebService
    15 {
    16     public partial class Form1 : Form
    17     {
    18         public Form1()
    19         {
    20             InitializeComponent();
    21         }
    22         Socket listenSocket = null;
    23         /// <summary>
    24         /// 启动服务
    25         /// </summary>
    26         /// <param name="sender"></param>
    27         /// <param name="e"></param>
    28         private void BtnStar_Click(object sender, EventArgs e)
    29         {
    30             listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建监控Socket
    31             IPAddress iPAddress = IPAddress.Parse(txtIP.Text);//创建IP地址
    32             IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, Convert.ToInt32(txtPort.Text));//创建网络节点
    33             listenSocket.Bind(iPEndPoint);//绑定网络节点
    34             listenSocket.Listen(10);//监听队列10
    35             //只有监听到一个连接,代码才会继续往下走,会影响UI线程,所以开启一个线程专门监听
    36             Thread myThread = new Thread(BeginAccept);
    37             myThread.IsBackground = true;
    38             myThread.Start();
    39         }
    40         /// <summary>
    41         /// 监听浏览器发送的请求,当有浏览器发送请求时,创建一个新的Socket处理客户请求,使用死循环继续监听下一个用户的请求
    42         /// </summary>
    43         private void BeginAccept()
    44         {
    45             while (true)//监听Socket继续监听
    46             {
    47                 Socket socket = listenSocket.Accept();//将连接交给一个新创建的Socket
    48                 //对请求进行处理
    49                 HttpApplication httpApplication = new HttpApplication(socket, ShowMsg);
    50             }
    51         }
    52         /// <summary>
    53         /// 对跨线程访问进行处理
    54         /// </summary>
    55         /// <param name="msg"></param>
    56         private void ShowMsg(string msg)
    57         {
    58             if (txtMsg.InvokeRequired)
    59             {
    60                 txtMsg.Invoke(new Action<string>((mgs) =>
    61                 {
    62                     this.txtMsg.Text = msg+"
    ";
    63                 }), msg);
    64             }
    65         }
    66     }
    67 }

    使用HttpApplication类对发送来的请求做处理

     1 using System;
     2 using System.Collections.Generic;
     3 using System.IO;
     4 using System.Linq;
     5 using System.Net.Sockets;
     6 using System.Text;
     7 using System.Threading.Tasks;
     8 
     9 namespace MyWebServer
    10 {
    11     /// <summary>
    12     /// 完成客户端发送过来的数据的处理。
    13     /// </summary>
    14     public class HttpApplication
    15     {
    16         Socket newSocket = null;
    17         DGShowMsg dgShowMsg = null;
    18         /// <summary>
    19         /// HttpApplication构造函数
    20         /// </summary>
    21         /// <param name="newSocket">需要处理的Socket对象</param>
    22         /// <param name="dgShowMsg">窗体程序的文本框</param>
    23         public HttpApplication(Socket newSocket, DGShowMsg dgShowMsg)
    24         {
    25             this.newSocket = newSocket;
    26             this.dgShowMsg = dgShowMsg;
    27             //接收客户端发送过来的数据.
    28             byte[] buffer = new byte[1024 * 1024 * 2];
    29             int receiveLength = newSocket.Receive(buffer);//接收客户端发送过来的数据,返回的是实际接收的数据的长度。
    30             //如果发过来的请求有数据,才进行处理
    31             if (receiveLength > 0)
    32             {
    33                 string msg = System.Text.Encoding.UTF8.GetString(buffer, 0, receiveLength);
    34                 HttpRequst request = new HttpRequst(msg);
    35                 ProcessReuest(request);
    36                 dgShowMsg(msg);
    37             }
    38         }
    39         /// <summary>
    40         /// 对请求做处理,并响应
    41         /// </summary>
    42         /// <param name="request"></param>
    43         public void ProcessReuest(HttpRequst request)
    44         {
    45             string filePath = request.FilePath;
    46             string dataDir = AppDomain.CurrentDomain.BaseDirectory;//获得当前服务器程序的运行目录
    47             if (dataDir.EndsWith(@"inDebug") || dataDir.EndsWith(@"inRelease"))
    48             {
    49                 dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
    50             }
    51             string fullDir = dataDir + filePath;//获取文件完整路径。
    52             using (FileStream fileStream = new FileStream(fullDir, FileMode.Open, FileAccess.Read))
    53             {
    54                 byte[] buffer = new byte[fileStream.Length];
    55                 fileStream.Read(buffer, 0, buffer.Length);
    56                 //构建响应报文。
    57                 HttpResponse response = new HttpResponse(buffer, filePath);
    58                 newSocket.Send(response.GetHeaderResponse());//返回响应头.
    59                 newSocket.Send(buffer);
    60             }
    61         }
    62     }
    63 }

    这是请求报文

    GET /Show.html HTTP/1.1

    Host: 127.0.0.1:9876

    Connection: keep-alive

    Upgrade-Insecure-Requests: 1

    User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3554.0 Safari/537.36

    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

    Accept-Encoding: gzip, deflate, br

    Accept-Language: zh-CN,zh;q=0.9

    HttpRequest类:对请求报文头进行处理

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace MyWebService
     8 {
     9     public class HttpRequest
    10     {
    11         /// <summary>
    12         /// 请求文件相对路径
    13         /// </summary>
    14         public string filePath { get; set; }
    15         public HttpRequest(string msg)
    16         {
    17             filePath = msg.Split(' ')[1];
    18         }
    19     }
    20 }

    HttpResponse类

     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 
     8 namespace MyWebService
     9 {
    10     public class HttpResponse
    11     {
    12         byte[] buffer;
    13         /// <summary>
    14         /// 报文体返回类型
    15         /// </summary>
    16         public string Content_Type { get; set; }
    17         /// <summary>
    18         /// HttpResponse构造函数
    19         /// </summary>
    20         /// <param name="buffer">报文体字节数组</param>
    21         /// <param name="fliePath">文件绝对路径</param>
    22         public HttpResponse(byte[] buffer, string fliePath)
    23         {
    24             this.buffer = buffer;
    25             string fileExt = Path.GetExtension(fliePath);//获取响应文件扩展名,返回相应的报文体返回类型
    26             switch (fileExt)
    27             {
    28                 case ".html":
    29                     Content_Type = "text/html";
    30                     break;
    31             }
    32         }
    33         /// <summary>
    34         /// 获取返回报文头
    35         /// </summary>
    36         /// <returns></returns>
    37         public byte[] GetResonseHead()
    38         {
    39             StringBuilder builder = new StringBuilder();
    40             builder.Append("HTTP/1.1 200 ok
    ");
    41             builder.Append("Content-Type:" + Content_Type + ";charset=utf-8
    ");
    42             builder.Append("Content-Length:" + buffer.Length + "
    
    ");//在相应报文头的最后一行下面有一个空行,所以在这里加两组"
    "
    43             return System.Text.Encoding.UTF8.GetBytes(builder.ToString());
    44         }
    45     }
    46 }

    Show.html

    <!DOCTYPE html>

    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">

    <head>

        <meta charset="utf-8" />

        <title></title>

    </head>

    <body>

        我的博客.

    </body>

    </html>

    最后我们来用一下

    点击启动调试,然后启动服务

     

     然后再浏览器输入,请求地址

     最后的结果就是

     

  • 相关阅读:
    基础面试
    三级联动
    数据库分裤分表操作
    缓存的三种方式
    php部分--session的三种用法
    css
    数组
    生成中国地区随机IP
    xml的读取
    React入门
  • 原文地址:https://www.cnblogs.com/birdGe/p/11885129.html
Copyright © 2020-2023  润新知