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

场景是项目需要在客户端控制台软件和.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, , data.Length);
s.Flush();
}
bytes = o.ToArray();
}
return bytes;
}

3.GZip解压

        private const int BUFFER_LENGTH = ;
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 = ;
byte[] buffer = new byte[BUFFER_LENGTH];
while ((size = s.Read(buffer, , buffer.Length)) > )
{
o.Write(buffer, , 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, , 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 = ;
MemoryStream ms = new MemoryStream();
byte[] buffer = new byte[bufferSize];
while (true)
{
int size = responseStream.Read(buffer, , bufferSize);
if (size == ) break;
ms.Write(buffer, , 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, , 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, , headerbytes.Length);
memStream.Write(dataBytes, , 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, , boundarybytes.Length); //设置请求长度
uploadRequest.ContentLength = memStream.Length;
//获取请求写入流
Stream requestStream = uploadRequest.GetRequestStream(); //将内存流数据读取位置归零
memStream.Position = ;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, , tempBuffer.Length);
memStream.Close(); //将内存流中的buffer写入到请求写入流
requestStream.Write(tempBuffer, , 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 <= ) 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, , fileContentLength);
return fileBytes;
}
}
return null;
}

.NET BS端和CS端相互压缩发送接收byte对象数据方法的更多相关文章

  1. Web自定义协议,BS端启动CS端,

    实例 1.准备CS项目,windows窗体应用程序,拖进来一个label控件来接受BS的参数,并显示,右击生成,复制该文件的bin目录下的exe,例如放在以下路径,例如C:\\simu\\下, 2.编 ...

  2. hadoop的压缩解压缩,reduce端join,map端join

    hadoop的压缩解压缩 hadoop对于常见的几种压缩算法对于我们的mapreduce都是内置支持,不需要我们关心.经过map之后,数据会产生输出经过shuffle,这个时候的shuffle过程特别 ...

  3. 在浏览器端用H5实现图片压缩上传

    一.需求的场景: 在我们的需求中需要有一个在手机浏览器端,用户实现上传证件照片的功能,我们第一版上了一个最简版,直接让用户在本地选择图片,然后上传到公司公共的服务器上. 功能实现后我们发现一个问题,公 ...

  4. 常看常遇见之一——BS架构VS CS架构

    常看常遇见之一——BS架构VS CS架构 1.BS架构 即Browser/Server(浏览器/服务器)结构,是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构.在这种结构下,用户 ...

  5. C# 移动端与PC端的数据交互

    小记:针对目前功能越来越强大的智能手机来说,在PC端支持对手机中的用户数据作同步.备份以及恢复等保护措施的应用已经急需完善.不仅要对数据作保护,而且用户更希望自己的手机跟PC能够一体化,以及和远程服务 ...

  6. 软件的三大类型-单机类型、BS类型、CS类型

    单机类型:最开始的软件就是那些不需要联网的单机软件. CS类型:有的程序需要统一管理软件中使用的数据, 所以就将保存数据的数据库统一存放在一台主机中, 所有的用户在需要数据时都要从主机获取, 这时就分 ...

  7. web端,app端,小程序端测试差异详解

    前置解释:1.单纯从功能测试的层面上来讲的话,APP 测试.web 测试和H5测试在流程和功能测试上是没有区别的2.Web项目或pc项目都是在电脑上进行测试的.常见的PC项目架构有BS架构和CS架构的 ...

  8. 淘宝购物车页面 PC端和移动端实战

    最近花了半个月的时间,做了一个淘宝购物车页面的Demo.当然,为了能够更加深入的学习,不仅仅有PC端的固定宽度的布局,还实现了移动端在Media Query为768px以下(也就是实现了ipad,ip ...

  9. PC端和移动端在前端开发上的一些区别,前端里移动端到底比pc端多哪些知识

    (1)———————— 前端里移动端到底比pc端多哪些知识,为啥面试时好多公司都问h5水平如何?我做过几年的web前端开发,就简单谈谈自己的感受吧.首先来看看PC端和移动端在前端开发上的一些区别: ( ...

随机推荐

  1. Mybatis/Ibatis,数据库操作的返回值

    该问题,我百度了下,根本没发现什么有价值的文章:还是看源代码(详见最后附录)中的注释,最有效了!insert,返回值是:新插入行的主键(primary key):需要包含<selectKey&g ...

  2. Pytorch学习记录-torchtext和Pytorch的实例( 使用神经网络训练Seq2Seq代码)

    Pytorch学习记录-torchtext和Pytorch的实例1 0. PyTorch Seq2Seq项目介绍 1. 使用神经网络训练Seq2Seq 1.1 简介,对论文中公式的解读 1.2 数据预 ...

  3. js毫秒数转天时分秒

    formatDuring: function(mss) {   var days = parseInt(mss / (1000 * 60 * 60 * 24));   var hours = pars ...

  4. java的System.currentTimeMillis()如何转换成C#的DateTime.Now.Ticks?

    考虑到我们是东八时区的话,应做如下转换: long milli = System.currentTimeMillis() + 8*3600*1000; long ticks = (milli*1000 ...

  5. ubuntu 运行级别initlevel

    Linux 系统任何时候都运行在一个指定的运行级上,并且不同的运行级的程序和服务都不同,所要完成的工作和要达到的目的都不同,系统可以在这些运行级之间进行切换,以完成不同的工作.Ubuntu 的系统运行 ...

  6. Centos 6.5 配置hadoop2.7.1

    1 Centos 6.5 编译hadoop2.7.1 主机配置: sudo yum install gcc gcc-c++ sudo yum install ncurses-devel sudo yu ...

  7. Java一行代码可声明多个同类变量

    Java支持一句语句声明多个同类变量. Example: String a = "Hello", c = "hello"; int x = 5, y = 5;

  8. python基础十三之内置函数

    内置函数 操作字符串代码 eval和exec print(eval('1+2')) # 简单的计算 有返回值 exec('for i in range(10):print(i)') # 简单的流程控制 ...

  9. js实现小数点四舍五入

    js实现小数点四舍五入 其实这个问题,在之前的面试中被提问到了,由于笔者平时都是用原生的toFixed()的方法来保留小数点,所以当时并没有回答出来这个问题,呜呜呜~.~

  10. H3C DHCP中继基本配置