当前位置:首页 > C# > 正文

C# 实现网络流的分块传输编码(详解 Chunked Transfer Encoding 在 C# 中的应用)

在现代 Web 开发中,C# 分块传输编码(Chunked Transfer Encoding)是一种非常实用的技术,尤其适用于服务器无法预先知道响应体总长度的场景。例如:实时日志推送、视频流、大数据导出等。本文将手把手教你如何在 C# 中使用 HttpListener 实现分块传输编码,即使你是编程小白也能轻松上手!

什么是分块传输编码?

分块传输编码(Chunked Transfer Encoding)是 HTTP/1.1 协议中定义的一种数据传输机制。它允许服务器将响应体分成多个“块”(chunks)逐个发送,而无需提前知道整个响应的大小。每个块前面都有一个十六进制数字表示该块的字节数,最后以一个大小为 0 的块表示结束。

C# 实现网络流的分块传输编码(详解 Chunked Transfer Encoding 在 中的应用) 分块传输编码 HttpListener 分块响应 网络流处理 第1张

为什么使用分块传输编码?

  • 无需预知响应体总长度,节省内存
  • 支持实时流式输出(如直播、日志)
  • 提升用户体验,用户可边接收边处理数据

C# 中实现分块传输编码

在 .NET 中,我们可以使用 HttpListener 类来创建一个简单的 HTTP 服务器,并通过设置响应头 Transfer-Encoding: chunked 来启用分块传输。

步骤 1:创建 HttpListener 并监听请求

using System;using System.IO;using System.Text;using System.Net;class Program{    static void Main()    {        var listener = new HttpListener();        listener.Prefixes.Add("http://localhost:8080/");        listener.Start();        Console.WriteLine("服务器启动,监听 http://localhost:8080/");        while (true)        {            var context = listener.GetContext();            HandleRequest(context);        }    }}

步骤 2:配置响应头并写入分块数据

关键点在于:不要设置 Content-Length,而是设置 Transfer-Encoding: chunked,然后按格式写入每个块。

static void HandleRequest(HttpListenerContext context){    var response = context.Response;    var output = response.OutputStream;    // 启用分块传输编码    response.SendChunked = true;    response.ContentType = "text/plain; charset=utf-8";    // 模拟分块发送数据    for (int i = 1; i <= 5; i++)    {        string chunkData = $"这是第 {i} 块数据\n";        byte[] buffer = Encoding.UTF8.GetBytes(chunkData);        // 写入块大小(十六进制)        string chunkSize = buffer.Length.ToString("x");        byte[] sizeLine = Encoding.ASCII.GetBytes(chunkSize + "\r\n");        output.Write(sizeLine, 0, sizeLine.Length);        // 写入块数据        output.Write(buffer, 0, buffer.Length);        // 写入块结束符 \r\n        output.Write(Encoding.ASCII.GetBytes("\r\n"), 0, 2);        // 刷新并模拟延迟        output.Flush();        System.Threading.Thread.Sleep(1000);    }    // 发送最后一个空块表示结束    output.Write(Encoding.ASCII.GetBytes("0\r\n\r\n"), 0, 5);    output.Close();}

注意:在实际开发中,你可以使用 response.SendChunked = true; 让 .NET 自动处理分块格式,无需手动拼接十六进制头和 \r\n。但为了教学目的,上面代码展示了底层原理。

简化写法:使用 SendChunked 属性

其实 .NET 已经封装好了分块逻辑,你只需设置 SendChunked = true,然后像普通流一样写入数据即可:

static void SimpleChunkedResponse(HttpListenerContext context){    var response = context.Response;    response.SendChunked = true;    response.ContentType = "text/plain; charset=utf-8";    using (var writer = new StreamWriter(response.OutputStream, Encoding.UTF8))    {        for (int i = 1; i <= 3; i++)        {            writer.WriteLine($"自动分块:消息 {i}");            writer.Flush();            System.Threading.Thread.Sleep(500);        }    } // 关闭时会自动发送 0\r\n\r\n    response.Close();}

常见问题与注意事项

  • 确保客户端支持 HTTP/1.1(几乎所有现代浏览器都支持)
  • 不要同时设置 Content-LengthTransfer-Encoding: chunked,否则可能出错
  • 在 ASP.NET Core 中,推荐使用 IHttpResponseBodyFeature 或 SignalR 处理流式响应

总结

通过本文,你已经掌握了 HttpListener 分块响应 的基本实现方法。无论是用于 C# 网络流处理 还是构建实时应用,Chunked Transfer Encoding C# 都是一个强大而灵活的工具。希望这篇教程能帮助你轻松入门分块传输编码!

动手试试吧!修改代码,发送 JSON、HTML 甚至二进制数据,体验分块传输的魅力。