.NET BS端和CS端相互压缩发送接收byte对象数据方法

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

.NET BS端和CS端相互压缩发送接收byte对象数据方法

Z语言   2020-01-08 我要评论

本文是总结实际项目经验,代码不少是学习别人整合的,效果稳定可靠,有很大参考价值;但是也有不全面的地方,朋友们拿到可以按照自己需要修改。

场景是项目需要在客户端控制台软件和.NET MVC站点间互相传递数据,数据的量比较大,需要对数据进行转化为byte数据,再压缩后发送,接收方需要接收byte数据,再解压缩,还原成数据。

本文既有Web端发送接收数据,也有CS端发送接收数据,内容比较全面。

 

一、object和byte互转

object和byte互转是基础步骤,实现过程是很简单的,需要用到MemoryStream 、IFormatter 等类。

 

1、导入命名空间

using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

 

2、object转byte方法

        public static byte[] ToBytes(object obj)
        {
            if (obj == null) return null;
            byte[] buff;
            using (MemoryStream ms = new MemoryStream())
            {
                IFormatter iFormatter = new BinaryFormatter();
                iFormatter.Serialize(ms, obj);
                buff = ms.GetBuffer();
            }
            return buff;
        }

 

 

3. byte转object

  

        public static object ToObject(byte[] bytes)
        {
            if (bytes == null) return null;
            object obj;
            using (MemoryStream ms = new MemoryStream(bytes))
            {
                IFormatter iFormatter = new BinaryFormatter();
                obj = iFormatter.Deserialize(ms);
            }
            return obj;
        }

 

二、使用SharpZipLib进行GZip压缩和解压

经过反复实现修改,我感觉用开源类库ICSharpCode.SharpZipLib进行GZip压缩解压比.NET自带的System.IO.Compression.GZipStream效果更好。自己感觉,数据读取成DataTable压缩,不如把DataTable转化为实体类列表进行压缩效果好。

ICSharpCode.SharpZipLib你可以很容易从网络上获取到。

如果发送方对数据进行GZip压缩,接收方必须要对数据进行GZip解压。

 

1、导入命名空间

using ICSharpCode.SharpZipLib.GZip;
using System.IO;

 

2.GZip压缩

        public static byte[] GZipCompress(byte[] data)
        {
            byte[] bytes = null;
            using (MemoryStream o = new MemoryStream())
            {
                using (Stream s = new GZipOutputStream(o))
                {
                    s.Write(data, 0, data.Length);
                    s.Flush();
                }
                bytes = o.ToArray();
            }
            return bytes;
        }

 

3.GZip解压

        private const int BUFFER_LENGTH = 2048;
        public static byte[] GZipDecompress(byte[] data)
        {
            byte[] bytes = null;
            using (MemoryStream o = new MemoryStream())
            {
                using (MemoryStream ms = new MemoryStream(data))
                {
                    using (Stream s = new GZipInputStream(ms))
                    {
                        s.Flush();
                        int size = 0;
                        byte[] buffer = new byte[BUFFER_LENGTH];
                        while ((size = s.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            o.Write(buffer, 0, size);
                        }
                    }
                }
                bytes = o.ToArray();
            }
            return bytes;
        }

 

三、Controller发送byte和控制台程序接收byte

 

1.Controller发送byte

在.NET MVC的Controller类中发送数据很简单,用Response进行如下发送就可以了,当然事先要把数据转化成byte,可以压缩也可以不压缩;但是这里的ContentType 内容表明这个数据是经过GZip压缩的。

        private void SendBytes(byte[] bytes)
        {
            Response.ClearContent();
            Response.ContentType = "application/x-zip-compressed";//发送的是gzip格式
            Response.BinaryWrite(bytes);
            Response.End();
        } 

2.控制台程序接收byte

虽然说是Controller发送byte,其实是控制台程序访问了某个url后Controller才发送数据,因此这里用PostBinary首先进行访问。

        public static byte[] PostBinary(string url, string body, CookieContainer cookie)
        {
            HttpWebRequest request = CreateRequest(url, body, cookie);
            HttpWebResponse response = GetResponse(request);
            byte[] bytes = ReadAllBytes(response);
            return bytes;
        }

 

        private static HttpWebRequest CreateRequest(string url, string body, CookieContainer cookie)
        {
            Encoding encoding = Encoding.UTF8;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.Accept = "text/html, application/xhtml+xml, */*";
            request.ContentType = "application/x-www-form-urlencoded";
            request.CookieContainer = cookie;

            byte[] buffer = encoding.GetBytes(body);
            request.ContentLength = buffer.Length;
            request.GetRequestStream().Write(buffer, 0, buffer.Length);
            return request;
        }

 

        private static HttpWebResponse GetResponse(HttpWebRequest request)
        {
            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }
            return response;
        }

 

 

ReadAllBytes方法要用到MemoryStream 类。

        public static byte[] ReadAllBytes(HttpWebResponse response)
        {
            Stream responseStream = response.GetResponseStream();
            int bufferSize = 2048;
            MemoryStream ms = new MemoryStream();
            byte[] buffer = new byte[bufferSize];
            while (true)
            {
                int size = responseStream.Read(buffer, 0, bufferSize);
                if (size == 0) break;
                ms.Write(buffer, 0, size);
            }
            byte[] responseBytes = ms.ToArray();
            return responseBytes;
        }

 

 

四、控制台程序发送byte和Controller接收byte

这一部分和上一部分相反。控制台程序发送byte其实和向网站上传文件一样,Controller接收byte其实也和接收上传的文件一样。

 

1.控制台程序发送byte

这是是用HttpWebRequest给指定url上传文件,文件当然是按byte格式上传的。

        public static HttpWebResponse UploadBinary(string url, string dataName, object obj)
        {
            byte[] dataBytes = ObjectBinaryHelper.Compress(obj);
            if (dataBytes == null) dataBytes = new byte[] { };
            string boundary = DateTime.Now.Ticks.ToString("x");
            HttpWebRequest uploadRequest = (HttpWebRequest)WebRequest.Create(url);//url为上传的地址
            uploadRequest.ContentType = "multipart/form-data; boundary=" + boundary;
            uploadRequest.Method = "POST";
            uploadRequest.Accept = "*/*";
            uploadRequest.KeepAlive = true;
            uploadRequest.Headers.Add("Accept-Language", "zh-cn");
            uploadRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
            uploadRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            //uploadRequest.Headers["Cookie"] = cookie;//上传文件时需要的cookies

            //创建一个内存流
            Stream memStream = new MemoryStream();
            boundary = "--" + boundary;
            //添加上传文件参数格式边界
            string paramFormat = boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}\r\n";
            NameValueCollection param = new NameValueCollection();
            param.Add("fname", dataName);//写上参数
            foreach (string key in param.Keys)
            {
                string formitem = string.Format(paramFormat, key, param[key]);
                byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                memStream.Write(formitembytes, 0, formitembytes.Length);
            }

            //添加上传文件数据格式边界
            string dataFormat = boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";filename=\"{1}\"\r\nContent-Type:application/octet-stream\r\n\r\n";
            string header = string.Format(dataFormat, dataName, dataName);
            byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
            memStream.Write(headerbytes, 0, headerbytes.Length);
            memStream.Write(dataBytes, 0, dataBytes.Length);
            //添加文件结束边界
            byte[] boundarybytes = System.Text.Encoding.UTF8.GetBytes("\r\n\n" + boundary + "\r\nContent-Disposition: form-data; name=\"Upload\"\r\n\nSubmit Query\r\n" + boundary + "--");
            memStream.Write(boundarybytes, 0, boundarybytes.Length);

            //设置请求长度
            uploadRequest.ContentLength = memStream.Length;
            //获取请求写入流
            Stream requestStream = uploadRequest.GetRequestStream();

            //将内存流数据读取位置归零
            memStream.Position = 0;
            byte[] tempBuffer = new byte[memStream.Length];
            memStream.Read(tempBuffer, 0, tempBuffer.Length);
            memStream.Close();

            //将内存流中的buffer写入到请求写入流
            requestStream.Write(tempBuffer, 0, tempBuffer.Length);
            requestStream.Close();

            //获取到上传请求的响应
            HttpWebResponse response = GetResponse(uploadRequest);
            return response;
        }

 

2.Controller接收byte

Controller接收byte也等同于接收文件,这里的参数name是文件名称。

        protected byte[] GetHttpBinary(string name)
        {
            if (this.Request.Files == null || this.Request.Files.Count <= 0) return null;
            foreach (string key in this.Request.Files.Keys)
            {
                if (key == name)
                {
                    HttpPostedFileBase httpPostedFile = this.Request.Files[key];
                    int fileContentLength = httpPostedFile.ContentLength;
                    byte[] fileBytes = new byte[fileContentLength];
                    //创建Stream对象,并指向上传文件
                    Stream fileStream = httpPostedFile.InputStream;
                    //从当前流中读取字节,读入字节数组中
                    fileStream.Read(fileBytes, 0, fileContentLength);
                    return fileBytes;
                }
            }
            return null;
        }

 

 

 

 

 

 

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们