来自:http://developer.51cto.com/art/201002/185444.htm

WCF传送二进制流数据基本实现步骤详解

2010-02-26 16:10 佚名 CSDN  

WCF传送二进制流数据的相关操作方法在实际应用中是一个比较基础的操作应用。我们在这里将会针对此做一个详细介绍。

 

我们知道,在实现WCF传送二进制流数据这一操作过程中,会有一些限制因素。我们在实际应用中要特别注意这一点。今天我们就会针对这方面的问题做一个详细的介绍,希望对大家有所帮助。

只有 BasicHttpBinding、WebHttpBinding、NetTcpBinding 和 NetNamedPipeBinding 支持传送流数据。
流数据类型必须是可序列化的 Stream 或 MemoryStream。
传递时消息体(Message Body)中不能包含其他数据。

我们先看看下面的WCF传送二进制流数据例子。

注意将 Binding.TransferMode 设置为 TransferMode.Streamed,我们还可以修改 Binding.MaxReceivedMessageSize 来调整消息大小(默认是64KB)。

    [ServiceContract]
public interface IFileService
{
[OperationContract]
void Upload(Stream stream);
}
public class FileService : IFileService, IDisposable
{
public void Upload(Stream stream)
{
FileStream file = new FileStream("test.dll", FileMode.Create);
try
{
BinaryWriter writer = new BinaryWriter(file);
BinaryReader reader = new BinaryReader(stream);
byte[] buffer; do { buffer = reader.ReadBytes(); writer.Write(buffer); } while (buffer.Length > );
}
finally
{
file.Close();
stream.Close();
}
}
public void Dispose()
{
Console.WriteLine("Dispose...");
}
}
public class WcfTest
{
public static void Test()
{
AppDomain.CreateDomain("Server").DoCallBack(delegate
{
ServiceHost host = new ServiceHost(typeof(FileService), new Uri("http://localhost:8080/FileService"));
BasicHttpBinding binding = new BasicHttpBinding();
binding.TransferMode = TransferMode.Streamed;
host.AddServiceEndpoint(typeof(IFileService), binding, "");
host.Open();
});
BasicHttpBinding binding2 = new BasicHttpBinding();
binding2.TransferMode = TransferMode.Streamed;
IFileService channel = ChannelFactory<IFileService>.CreateChannel(binding2, new EndpointAddress("http://localhost:8080/FileService"));
using (channel as IDisposable)
{
FileStream stream = new FileStream("MyLibrary2.dll", FileMode.Open);
channel.Test(stream);
stream.Close();
}
}
}

一切正常。那么 "传递时消息体(Memory Body)中不能包含其他数据" 是什么意思?我们修改一下上面的契约,除了传递文件流外,我们还希望传递文件名。

    [ServiceContract]
public interface IFileService
{
[OperationContract]
void Upload(string filename, Stream stream);
}
// ... 其他代码暂略 ...

当你修改完WCF传送二进制流数据的代码后,运行时你发现触发了一个 InvalidOperationException 异常。

未处理 System.InvalidOperationException
Message="For request in operation Upload to be a stream the operation must have a single parameter whose type is Stream."
Source="System.ServiceModel"

那么该怎么办呢?DataContract 肯定不行。 没错!你应该记得 MessageContract,将 filename 放到 MessageHeader 里面就行了。

    [MessageContract]
public class FileData
{
[MessageHeader]
public string filename;
[MessageBodyMember]
public Stream data;
}
[ServiceContract]
public interface IFileService
{
[OperationContract]
void Upload(FileData file);
}
public class FileService : IFileService, IDisposable
{
public void Upload(FileData file)
{
FileStream f = new FileStream(file.filename, FileMode.Create);
try
{
BinaryWriter writer = new BinaryWriter(f);
BinaryReader reader = new BinaryReader(file.data);
byte[] buffer;
do
{
buffer = reader.ReadBytes(); writer.Write(buffer);
} while (buffer.Length > );
}
finally
{
f.Close(); file.data.Close();
}
}
public void Dispose()
{
Console.WriteLine("Dispose...");
}
}
public class WcfTest
{
public static void Test()
{
AppDomain.CreateDomain("Server").DoCallBack(delegate
{
ServiceHost host = new ServiceHost(typeof(FileService), new Uri("http://localhost:8080/FileService"));
BasicHttpBinding binding = new BasicHttpBinding();
binding.TransferMode = TransferMode.Streamed;
host.AddServiceEndpoint(typeof(IFileService), binding, "");
host.Open();
});
BasicHttpBinding binding2 = new BasicHttpBinding();
binding2.TransferMode = TransferMode.Streamed;
IFileService channel = ChannelFactory<IFileService>.CreateChannel(binding2, new EndpointAddress("http://localhost:8080/FileService"));
using (channel as IDisposable)
{
FileData file = new FileData();
file.filename = "test2.dll";
file.data = new FileStream("MyLibrary2.dll", FileMode.Open);
channel.Upload(file); file.data.Close();
}
}
}

问题解决了。上面的例子使用 BaseHttpBinding,如果使用 NetTcpBinding,相信速度要快很多。除了向服务器传送流外,也可反向返回流数据。

    [ServiceContract]
public interface IFileService
{
[OperationContract]
void Upload(Stream stream);
[OperationContract]
Stream Download(string filename);
}

虽然服务器在操作结束时会自动关闭客户端 Request Stream,但个人建议还是使用 try...finnaly... 自主关闭要好一些,因为意外总是会发生的。

WCF传送二进制流数据的全部操作方法就为大家介绍到这里。

转:WCF传送二进制流数据基本实现步骤详解的更多相关文章

  1. Jmeter入门13 jmeter发送application/octet-stream二进制流数据

    http接口请求header里面 content-type: application/octet-stream  (二进制流数据),如何用jmeter发送请求? 1 添加http请求头 2 http请 ...

  2. [转帖]IP /TCP协议及握手过程和数据包格式中级详解

    IP /TCP协议及握手过程和数据包格式中级详解 https://www.toutiao.com/a6665292902458982926/ 写的挺好的 其实 一直没闹明白 网络好 广播地址 还有 网 ...

  3. Oracle10g数据泵impdp参数详解--摘自网络

    Oracle10g数据泵impdp参数详解 2011-6-30 12:29:05 导入命令Impdp •      ATTACH 连接到现有作业, 例如 ATTACH [=作业名]. •      C ...

  4. Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解

    返回<8天掌握EF的Code First开发>总目录 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LINQ to ...

  5. 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解

    本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...

  6. <转>ASP.NET学习笔记之MVC 3 数据验证 Model Validation 详解

    MVC 3 数据验证 Model Validation 详解  再附加一些比较好的验证详解:(以下均为引用) 1.asp.net mvc3 的数据验证(一) - zhangkai2237 - 博客园 ...

  7. python数据分析数据标准化及离散化详解

    python数据分析数据标准化及离散化详解 本文为大家分享了python数据分析数据标准化及离散化的具体内容,供大家参考,具体内容如下 标准化 1.离差标准化 是对原始数据的线性变换,使结果映射到[0 ...

  8. ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践

    写在前面 :从提出需求到完美的解决问题,实现过程是曲折的. 需求:在前(web client)后(Restful Service)端完全解耦的模式框架下,webclient需要请求 Service 返 ...

  9. socket传送二进制流的一些总结

    第一次实质性的接触socket通信方面的工作,所以遇到的问题还真不少,写篇博客记录一下,提升下记忆. 需求是通过私有协议进行二进制数据的传输,必须保证数据包不能被丢失,所以选择tcp的socket进行 ...

随机推荐

  1. MySQL 5.5加主键锁读问题【转载】

    背景      有同学讨论到MySQL 5.5下给大表加主键时会锁住读的问题,怀疑与fast index creation有关,这里简单说明下. 对照现象          为了说明这个问题的原因,有 ...

  2. (1.14)mysql锁问题之MyIsam

    1.mysql锁概述 BDB被InnoDB代替了,MyIsam在8.0也被抛弃了 2.MyIsam表锁(读写是串行的) [2.1]查看表锁争用情况. MyIsam存储引擎只支持表锁. 查看表锁争用情况 ...

  3. 调用finecms栏目多图怎么实现

    finecms栏目自定义字段添加图集怎么调用出来?已经上传两张图片了,点击可以预览图片,前端显示不了,如下图所示.调用栏目多图这个要涉及到二次开发,首先要先添加栏目自定义字段,设为文件的格式,然后可以 ...

  4. 爬虫解析库——BeautifulSoup

    解析库就是在爬虫时自己制定一个规则,帮助我们抓取想要的内容时用的.常用的解析库有re模块的正则.beautifulsoup.pyquery等等.正则完全可以帮我们匹配到我们想要住区的内容,但正则比较麻 ...

  5. what's the python之可迭代对象、迭代器与生成器(附面试题)

    可迭代对象 字符串.列表.元祖.集合.字典都是可迭代的,数字是不可迭代的.(可以用for循环遍历取出内部元素的就是可迭代的) 如何查看一个变量是否为可迭代: from collections impo ...

  6. Nancy Web框架 文档

    http://liulixiang1988.github.io/nancy-webkuang-jia.html 中文 https://github.com/NancyFx/Nancy/wiki/Doc ...

  7. DataTable 指定位置添加列

    dt.Columns.Add("id").SetOrdinal(指定位置);

  8. python中base64编码与解码

    在python3中用base64进行编码和解码的时候特别注意: 题目要求: 准备一张.jpg图片,比如:mm.jpg,读取图片数据并通过b85encode加密之后写入到新文件mm.txt文件中,然后读 ...

  9. NYOJ 圈水池

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #i ...

  10. vue中computed和watch的用法

    computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理: computed比较适合对多个变量或 ...