C# HttpListener 接收 post 数据

  public class HttpListenerPostParaHelper
    {
        private HttpListenerContext request;

        public HttpListenerPostParaHelper(HttpListenerContext request)
        {
            this.request = request;
        }

        private bool CompareBytes(byte[] source, byte[] comparison)
        {
            try
            {
                int count = source.Length;
                if (source.Length != comparison.Length)
                    return false;
                for (int i = 0; i < count; i++)
                    if (source[i] != comparison[i])
                        return false;
                return true;
            }
            catch
            {
                return false;
            }
        }

        private byte[] ReadLineAsBytes(Stream SourceStream)
        {
            var resultStream = new MemoryStream();
            while (true)
            {
                int data = SourceStream.ReadByte();
                resultStream.WriteByte((byte)data);
                if (data == 10)
                    break;
            }
            resultStream.Position = 0;
            byte[] dataBytes = new byte[resultStream.Length];
            resultStream.Read(dataBytes, 0, dataBytes.Length);
            return dataBytes;
        }
        //鱼 2022-06-23
        private byte[] ReadBytes(Stream SourceStream, byte[] ends)
        {
            List<byte> bytes = new List<byte>();
            while (true)
            {
                int data = SourceStream.ReadByte();
                if (data == -1) break;
                byte b = (byte)data;
                bytes.Add(b);
                if (bytes.Count >= ends.Length)
                {
                    bool ok = true;
                    for (int i = 0; i < ends.Length; i++)
                    {
                        if (ends[i] != bytes[(bytes.Count - ends.Length + i)])
                        {
                            ok = false;
                            break;
                        }
                    }
                    if (ok) break;
                }
            }
            return bytes.ToArray();
        }
        //鱼 2022-06-23 重写,解决换行符处理错误问题
        public List<HttpListenerPostValue> GetHttpListenerPostValue()
        {
            try
            {
                List<HttpListenerPostValue> HttpListenerPostValueList = new List<HttpListenerPostValue>();
                if (request.Request.ContentType.Length > 20 && string.Compare(request.Request.ContentType.Substring(0, 20), "multipart/form-data;", true) == 0)
                {
                    string[] HttpListenerPostValue = request.Request.ContentType.Split(';').Skip(1).ToArray();
                    string boundary = string.Join(";", HttpListenerPostValue).Replace("boundary=", "").Trim();

                    byte[] ChunkBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
                    byte[] EndBoundary = Encoding.ASCII.GetBytes("--" + boundary);// "--\r\n");
                    byte[] rnrn = Encoding.ASCII.GetBytes("\r\n\r\n");
                    byte[] __rn = Encoding.ASCII.GetBytes("--\r\n");
                    byte[] rn = Encoding.ASCII.GetBytes("\r\n");
                    Stream SourceStream = request.Request.InputStream;


                    System.Text.RegularExpressions.Regex regexName = new System.Text.RegularExpressions.Regex("; ?name=\"([^\"]+)");
                    System.Text.RegularExpressions.Regex regexFileName = new System.Text.RegularExpressions.Regex("filename=\"([^\"]+)");
                    System.Text.RegularExpressions.Regex regexType = new System.Text.RegularExpressions.Regex("Content-Type: ([^\r]+)");
                    while (true)
                    {
                        byte[] currentChunk = ReadBytes(SourceStream, rn);
                        if (CompareBytes(currentChunk, __rn) || currentChunk.Length < 2)
                        {
                            break;
                        }
                        if (CompareBytes(currentChunk, rn) || CompareBytes(ChunkBoundary, currentChunk))
                        {
                            byte[] heads = ReadBytes(SourceStream, rnrn);
                            string str = Encoding.UTF8.GetString(heads);
                            byte[] datas = ReadBytes(SourceStream, EndBoundary);

                            HttpListenerPostValue data = new HttpListenerPostValue();
                            data.Datas = new byte[datas.Length - EndBoundary.Length - 2];
                            if (data.Datas.Length > 0)
                                Buffer.BlockCopy(datas, 0, data.Datas, 0, data.Datas.Length);
                            var m = regexName.Match(str);
                            data.Name = m.Success ? m.Groups[1].Value : "";
                            m = regexType.Match(str);
                            data.ContentType = m.Success ? m.Groups[1].Value : "";
                            m = regexFileName.Match(str);
                            data.FileName = m.Success ? m.Groups[1].Value : "";
                            HttpListenerPostValueList.Add(data);
                        }
                    }
                }
                return HttpListenerPostValueList;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.StackTrace);
            }

        }
}

public class HttpListenerPostValue
    {
        public string ContentType { get; set; }
        public string FileName { get; set; }
        public string Name { get; set; }
        public byte[] Datas { get; set; }
  
        public override string ToString()
        {
            if (Datas == null || Datas.Length == 0) return "";
            return System.Text.UTF8Encoding.UTF8.GetString(Datas);
        }
    }

以前在网上找的一段代码,后来发现有bug,会删除上传数据里的换行符,然后我就重写了下。

看到有网友说效率能不能提高下,我抽时间优化了下,不使用读字节了,简单测试效率是原来的3倍左右

     /// <summary>
        /// 鱼 2022-12-12
        /// 修改:2022-12-13
        /// </summary>
        public class ReadStream : IDisposable
        {
            const int BufferSize = 64 * 1024;


            private Stream SourceStream;
            MemoryStream memoryStream = null;
            int index = 0;
            int length = 0;

            byte[] datas = new byte[BufferSize];
            public ReadStream(Stream SourceStream)
            {
                this.SourceStream = SourceStream;
            }

            public void Dispose()
            {
                if (memoryStream != null)
                {
                    memoryStream.Close();
                    memoryStream = null;
                }
            }

            int Find(int start, int end, byte[] bytes)
            {
                bool is_break;
                for (int i = start; i <= end - bytes.Length; i++)
                {
                    is_break = false;
                    for (int j = 0; j < bytes.Length; j++)
                    {
                        if (bytes[j] != datas[i + j])
                        {
                            is_break = true;
                            break;
                        }
                    }
                    if (!is_break)
                    {
                        return i;
                    }
                }
                return -1;
            }
            public byte[] ReadBytes(byte[] ends)
            {
                if (length == 0)
                {
                    length = SourceStream.Read(datas, 0, datas.Length);
                }
                int endsLength = ends.Length;
                while (true)
                {
                    int i = Find(index, length, ends);
                    if (i == -1)
                    {
                        if (length > endsLength)
                        {
                            if (memoryStream == null)
                            {
                                memoryStream = new MemoryStream();
                            }
                            memoryStream.Write(datas, index, length - endsLength - index + 1);
                            Buffer.BlockCopy(datas, length - endsLength + 1, datas, 0, endsLength - 1);
                            index = 0;
                            length = endsLength - 1;
                        }
                        int len = SourceStream.Read(datas, length, datas.Length - length);
                        if (len == 0)
                        {
                            break;
                        }
                        length += len;
                    }
                    else if (memoryStream != null)
                    {
                        int dataLen = i + endsLength;
                        memoryStream.Write(datas, 0, dataLen);
                        Buffer.BlockCopy(datas, dataLen, datas, 0, length - dataLen);
                        index = 0;
                        length -= dataLen;
                        byte[] result = memoryStream.ToArray();
                        memoryStream.Close();
                        memoryStream = null;
                        return result;
                    }
                    else
                    {
                        int dataLen = i + endsLength - index;

                        byte[] result = new byte[dataLen];
                        Buffer.BlockCopy(datas, index, result, 0, dataLen);

                        index += dataLen;

                        return result;
                    }
                }
                return new byte[] { };
            }
        }

使用

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要实现该功能,您需要将以下步骤分解为更小的任务: 1. 创建一个HttpListener对象并开始监听请求 2. 接收POST请求并读取请求实体中的数据 3. 将接收到的数据保存到本地文件中 下面是一个示例代码,可以帮助您完成这些任务: ```csharp using System; using System.IO; using System.Net; class Program { static void Main(string[] args) { HttpListener listener = new HttpListener(); listener.Prefixes.Add("http://localhost:8080/"); listener.Start(); Console.WriteLine("Listening..."); while (true) { HttpListenerContext context = listener.GetContext(); HttpListenerRequest request = context.Request; if (request.HttpMethod == "POST") { // 获取请求实体中的数据 using (Stream inputStream = request.InputStream) { byte[] buffer = new byte[4096]; int bytesRead; string fileName = Path.GetFileName(request.Url.LocalPath); using (FileStream outputStream = File.Create(fileName)) { while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0) { outputStream.Write(buffer, 0, bytesRead); } } Console.WriteLine($"File saved as {fileName}"); } context.Response.StatusCode = 200; } else { context.Response.StatusCode = 405; } context.Response.Close(); } } } ``` 这段代码创建了一个`HttpListener`对象,它监听来自`http://localhost:8080/`的请求。当请求方法为`POST`时,它将请求实体中的数据保存到本地文件中。您可以使用Postman等工具向该地址发送POST请求并上传文件。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值