找回密码
 立即注册
首页 业界区 安全 从20行代码理解HTTP服务器:用原始Socket揭开Web协议的 ...

从20行代码理解HTTP服务器:用原始Socket揭开Web协议的神秘面纱

凤清昶 4 天前
本文通过一个仅20行的C#代码示例,深入讲解HTTP服务器如何工作,帮助你理解浏览器和服务器之间的通信本质。
引言:HTTP的真相

当我们每天使用浏览器访问网站时,是否曾思考过背后发生了什么?浏览器和服务器之间到底在交流什么?今天,我将用最精简的代码(仅20行!)展示HTTP服务器的核心原理,并逐步扩展为一个功能完整的服务器。
核心代码:20行的HTTP服务器
  1. using System.Net;
  2. using System.Net.Sockets;
  3. using System.Text;
  4. class CoreHttpServer
  5. {
  6.     static void Main()
  7.     {
  8.         // 1. 创建TCP监听器
  9.         TcpListener server = new TcpListener(IPAddress.Any, 9011);
  10.         server.Start();
  11.         Console.WriteLine("服务器启动...");
  12.         while (true)
  13.         {
  14.             // 2. 接受连接
  15.             TcpClient client = server.AcceptTcpClient();
  16.             
  17.             // 3. 读取请求
  18.             NetworkStream stream = client.GetStream();
  19.             byte[] buffer = new byte[1024];
  20.             int bytes = stream.Read(buffer, 0, buffer.Length);
  21.             
  22.             // 4. 构建响应
  23.             string html = "<h1>Hello Socket!</h1><p>原始HTTP</p>";
  24.             string response =
  25.                 "HTTP/1.1 200 OK\r\n" +
  26.                 "Content-Type: text/html\r\n" +
  27.                 $"Content-Length: {Encoding.UTF8.GetByteCount(html)}\r\n" +
  28.                 "\r\n" + html;
  29.             
  30.             // 5. 发送响应
  31.             byte[] data = Encoding.UTF8.GetBytes(response);
  32.             stream.Write(data, 0, data.Length);
  33.             
  34.             client.Close();
  35.         }
  36.     }
  37. }
复制代码
这20行代码包含了HTTP服务器的一切本质!让我们逐行解析:
第一行:建立TCP连接通道
  1. TcpListener server = new TcpListener(IPAddress.Any, 9011);
复制代码
这行代码创建了一个TCP监听器,就像是开了一家商店,门牌号是9011:

  • IPAddress.Any:监听所有网络接口
  • 9011:端口号,服务器的"门牌号"
关键理解:HTTP建立在TCP之上。TCP是"可靠传输管道",HTTP是"管道中传输的文本协议"。
第二行:等待客户上门
  1. TcpClient client = server.AcceptTcpClient();
复制代码
当浏览器访问 http://localhost:9011 时:

  • 浏览器建立TCP连接到端口9011
  • AcceptTcpClient() 接受这个连接
  • 返回一个 TcpClient 对象,代表这个连接通道
第三行:接收浏览器的"订单"
  1. NetworkStream stream = client.GetStream();
  2. byte[] buffer = new byte[1024];
  3. int bytes = stream.Read(buffer, 0, buffer.Length);
复制代码
这里发生了以下事情:
  1. 浏览器发送的原始文本:
  2. GET / HTTP/1.1\r\n
  3. Host: localhost:9011\r\n
  4. User-Agent: Mozilla/5.0\r\n
  5. Accept: text/html\r\n
  6. \r\n
复制代码
注意最后的 \r\n\r\n(空行),这是HTTP协议规定的:头部结束的标记
第四行:准备"商品"(构建响应)
  1. string html = "<h1>Hello Socket!</h1><p>原始HTTP</p>";
  2. string response =
  3.     "HTTP/1.1 200 OK\r\n" +
  4.     "Content-Type: text/html\r\n" +
  5.     $"Content-Length: {Encoding.UTF8.GetByteCount(html)}\r\n" +
  6.     "\r\n" + html;
复制代码
HTTP响应由三部分组成:
1. 状态行:HTTP/1.1 200 OK


  • HTTP/1.1:协议版本
  • 200:状态码(成功)
  • OK:状态描述
2. 响应头部


  • Content-Type: text/html:告诉浏览器这是HTML
  • Content-Length: ...:告诉浏览器内容有多长(至关重要!
3. 空行分隔


  • \r\n:必须的空行,分隔头部和正文
4. 响应正文


  • HTML内容
第五行:发送"商品"给客户
  1. byte[] data = Encoding.UTF8.GetBytes(response);
  2. stream.Write(data, 0, data.Length);
  3. client.Close();
复制代码
文本 → 字节 → 通过网络发送 → 关闭连接。完整的一次HTTP交互完成!
从20行到完整服务器

现在,让我们基于这20行核心代码,构建一个功能更完整的服务器:
1. 添加请求解析
  1. // 解析浏览器请求的路径
  2. string requestText = Encoding.UTF8.GetString(buffer, 0, bytes);
  3. string[] lines = requestText.Split("\r\n");
  4. string requestLine = lines[0];
  5. string[] parts = requestLine.Split(' ');
  6. string path = parts.Length > 1 ? parts[1] : "/";
复制代码
这样我们就可以知道用户请求的是 /、/about 还是其他路径。
2. 根据路径返回不同内容
  1. string html;
  2. if (path == "/")
  3. {
  4.     html = "<h1>主页</h1>";
  5. }
  6. else if (path == "/about")
  7. {
  8.     html = "<h1>关于页面</h1>";
  9. }
  10. else
  11. {
  12.     html = "<h1>404 - 页面未找到</h1>";
  13. }
复制代码
3. 添加文件读取功能

这是从内存响应到文件系统的关键跨越:
[code]static string ReadHtmlFile(string fileName){    try    {        // 检查文件是否存在        if (!File.Exists(fileName))        {            throw new FileNotFoundException();        }                // 读取文件内容        string content = File.ReadAllText(fileName, Encoding.UTF8);        Console.WriteLine($"
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册