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 bytes = new List();
            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 GetHttpListenerPostValue()
        {
            try
            {
                List HttpListenerPostValueList = new List();
                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倍左右

     /// 
        /// 鱼 2022-12-12
        /// 修改:2022-12-13
        /// 
        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[] { };
            }
        }

使用

C# HttpListener 接收 post 数据_第1张图片

你可能感兴趣的:(c#,http)