You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于HttpListener与Mono的C#多部分表单文件上传处理问题

处理HttpListener下的multipart/form-data文件上传

核心处理思路

  1. 从请求的Content-Type头中解析出分隔符(boundary),这是区分multipart各数据块的核心标记
  2. 读取完整请求流,按boundary分割数据块
  3. 跳过每个块的头部信息(直到出现连续空行),仅提取后续的文件内容

适配Mono环境的代码实现

using System;
using System.IO;
using System.Net;
using System.Text;

class FileUploadServer
{
    static void Main(string[] args)
    {
        var listener = new HttpListener();
        listener.Prefixes.Add("http://localhost:8080/upload/");
        listener.Start();
        Console.WriteLine("服务器启动,等待上传请求...");

        while (true)
        {
            var context = listener.GetContext();
            var request = context.Request;
            var response = context.Response;

            // 过滤非POST和非multipart请求
            if (request.HttpMethod != "POST" || !request.ContentType.StartsWith("multipart/form-data"))
            {
                response.StatusCode = (int)HttpStatusCode.BadRequest;
                response.Close();
                continue;
            }

            // 解析分隔符
            var boundary = request.ContentType.Split(';')[1].Split('=')[1].Trim();
            var boundaryBytes = Encoding.UTF8.GetBytes($"--{boundary}");

            using (var reader = new BinaryReader(request.InputStream))
            using (var outputFile = new FileStream("uploaded_content.dat", FileMode.Create))
            {
                byte[] buffer = new byte[4096];
                int bytesRead;
                bool skipHeader = true;

                while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) > 0)
                {
                    if (skipHeader)
                    {
                        // 查找头部结束标记:连续两个换行\r\n\r\n
                        var contentStr = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                        var headerEndIdx = contentStr.IndexOf("\r\n\r\n");
                        if (headerEndIdx != -1)
                        {
                            // 写入头部之后的内容
                            var contentBytes = Encoding.UTF8.GetBytes(contentStr.Substring(headerEndIdx + 4));
                            outputFile.Write(contentBytes, 0, contentBytes.Length);
                            skipHeader = false;
                        }
                    }
                    else
                    {
                        // 检查是否到达结束分隔符,避免写入冗余内容
                        var boundaryPos = Array.IndexOf(buffer, boundaryBytes[0], 0, bytesRead);
                        if (boundaryPos != -1 && boundaryPos + boundaryBytes.Length <= bytesRead)
                        {
                            bool isMatch = true;
                            for (int i = 0; i < boundaryBytes.Length; i++)
                            {
                                if (buffer[boundaryPos + i] != boundaryBytes[i])
                                {
                                    isMatch = false;
                                    break;
                                }
                            }
                            if (isMatch)
                            {
                                // 写入分隔符前的有效内容后退出循环
                                outputFile.Write(buffer, 0, boundaryPos);
                                break;
                            }
                        }
                        outputFile.Write(buffer, 0, bytesRead);
                    }
                }
            }

            // 返回上传成功响应
            var responseBytes = Encoding.UTF8.GetBytes("文件内容提取完成");
            response.ContentLength64 = responseBytes.Length;
            response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
            response.Close();
        }
    }
}

关键细节说明

  • 分隔符处理:Content-Type中的boundary不带前缀--,拼接时需手动添加
  • 头部跳过逻辑:利用\r\n\r\n作为头部与内容的分隔标记,确保只提取有效文件数据
  • 字节流处理:用BinaryReader操作原始字节流,避免编码转换问题,后续支持图片上传时无需修改核心逻辑
  • 结束判断:检测到结束分隔符时立即停止写入,防止把分隔符、结尾标记等冗余内容写入文件

内容的提问来源于stack exchange,提问作者Pixel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 08:20:27