• 用 C# 自己动手编写一个 Web 服务器


    在.NET世界中,C#是一种功能强大的编程语言,常被用于构建各种类型的应用程序,包括Web服务器。虽然在实际生产环境中,我们通常会使用成熟的Web服务器软件(如IIS、Kestrel等),但了解如何用C#从头开始构建一个简单的Web服务器,对于深入理解HTTP协议和网络编程是非常有价值的。

    本文将指导你使用C#编写一个简单的Web服务器,并包含具体的代码实现。

    第一步:理解HTTP协议

    在编写Web服务器之前,我们需要对HTTP协议有一个基本的了解。HTTP是一种无状态的、基于请求和响应的协议。客户端(如Web浏览器)发送HTTP请求到服务器,服务器处理请求并返回HTTP响应。

    HTTP请求由请求行、请求头部和请求体组成。请求行包含请求方法(GET、POST等)、请求URL和HTTP协议版本。请求头部包含关于请求的附加信息,如HostUser-Agent等。请求体包含实际发送给服务器的数据,通常用于POST请求。

    HTTP响应由状态行、响应头部和响应体组成。状态行包含HTTP协议版本、状态码和状态消息。响应头部包含关于响应的附加信息,如Content-TypeContent-Length等。响应体包含服务器返回给客户端的实际数据。

    第二步:创建TCP监听器

    在C#中,我们可以使用TcpListener类来创建一个TCP监听器,用于监听传入的HTTP请求。以下是一个简单的示例代码,展示如何创建TCP监听器并等待连接:

    using System;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;
    
    class SimpleWebServer
    {
        private const int Port = 8080;
    
        public static void Main()
        {
            TcpListener listener = new TcpListener(IPAddress.Any, Port);
            listener.Start();
            Console.WriteLine($"Server started at http://localhost:{Port}/");
    
            while (true)
            {
                TcpClient client = listener.AcceptTcpClient();
                HandleClientAsync(client).Wait();
            }
        }
    
        private static async Task HandleClientAsync(TcpClient client)
        {
            NetworkStream stream = client.GetStream();
            StreamReader reader = new StreamReader(stream, Encoding.UTF8);
            StreamWriter writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true };
    
            try
            {
                // 读取请求行
                string requestLine = await reader.ReadLineAsync();
                if (string.IsNullOrEmpty(requestLine))
                    return;
    
                Console.WriteLine($"Received request: {requestLine}");
    
                // 解析请求行(为了简化,这里只处理GET请求)
                string[] parts = requestLine.Split(' ');
                if (parts.Length != 3 || parts[0] != "GET")
                {
                    SendErrorResponse(writer, 400, "Bad Request");
                    return;
                }
    
                string path = parts[1];
                if (path != "/")
                {
                    SendErrorResponse(writer, 404, "Not Found");
                    return;
                }
    
                // 发送响应
                SendResponse(writer, 200, "OK", "

    Hello, World!

    "
    ); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); SendErrorResponse(writer, 500, "Internal Server Error"); } finally { client.Close(); } } private static void SendResponse(StreamWriter writer, int statusCode, string statusMessage, string content) { writer.WriteLine($"HTTP/1.1 {statusCode} {statusMessage}"); writer.WriteLine("Content-Type: text/html; charset=UTF-8"); writer.WriteLine($"Content-Length: {content.Length}"); writer.WriteLine(); writer.Write(content); } private static void SendErrorResponse(StreamWriter writer, int statusCode, string statusMessage) { string content = $"

    {statusCode} {statusMessage}

    "
    ; SendResponse(writer, statusCode, statusMessage, content); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    这个示例代码创建了一个简单的Web服务器,监听8080端口。当客户端连接到服务器时,服务器会读取请求行,并根据请求路径返回相应的响应

  • 相关阅读:
    开发如何尽可能的避免BUG
    MayApps平台为政府机关后勤管理添“智慧”
    分类预测 | MATLAB实现SSA-FS-SVM麻雀算法同步优化特征选择结合支持向量机分类预测
    StarRocks 自增ID实现分页优化
    java基础面试题第二天
    Vue模板语法下集(03)
    智慧园区是未来发展的趋势吗?
    leetcode4 寻找两个正序数组的中位数
    CAD快捷键——修改类
    【Spring Boot】创建一个 Spring Boot 项目
  • 原文地址:https://blog.csdn.net/weixin_44837958/article/details/136700489