6 Wcf使用Stream传输

1.创建service和client项目

service项目新建wcf服务文件 MediaService 和 IMediaService 

IMediaService 代码为

 1 using System.IO;
 2 using System.ServiceModel;
 3 
 4 namespace Wcf_Stream_Service
 5 {
 6     // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IMediaService”。
 7     [ServiceContract]
 8     public interface IMediaService
 9     {
10         [OperationContract]
11         string[] GetMediaList();
12 
13         [OperationContract]
14         Stream GetMedia(string mediaName);
15     }
16 }

MediaService 代码为

 1 using System;
 2 using System.IO;
 3 
 4 namespace Wcf_Stream_Service
 5 {
 6     // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“MediaService”。
 7     public class MediaService : IMediaService
 8     {
 9         public Stream GetMedia(string mediaName)
10         {
11             string filePath = @"F:ProjectsLearn4SoftWcf_Stream_ServiceinDebug" + mediaName + ".txt";
12             if (!File.Exists(filePath))
13             {
14                 throw new Exception("不存在文件");
15             }
16             Stream s = null;
17             try
18             {
19                 s = new FileStream(filePath, FileMode.Open, FileAccess.Read);
20             }
21             catch (Exception)
22             {
23                 //如果发生异常了 我们就将流关闭释放
24                 s.Close();
25             }
26             return s;
27         }
28 
29         public string[] GetMediaList()
30         {
31             string[] mediaList = new string[3];
32             mediaList[0] = "lemon tree";
33             mediaList[1] = "yesterday";
34             mediaList[2] = "500 miles";
35             return mediaList;
36         }
37     }
38 }

service服务对应的app.Config内容为:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
      <!--bindings节点为自己新增的,旨在添加两个Streamed的传输,另外设置了最长信息接收量 最后为binding定义了一个名字-->
      <bindings>
        <basicHttpBinding>
          <binding name="newBasicHttpBinding" transferMode="Streamed" maxReceivedMessageSize="200000" />
        </basicHttpBinding>

        <netTcpBinding>
          <binding name="newNetTcpBinding" transferMode="Streamed" maxReceivedMessageSize="200000">
            <!--设置无安全-->
            <security mode ="None" />
          </binding>
        </netTcpBinding>
      </bindings>
      
        <services>
            <service name="Wcf_Stream_Service.MediaService">
              <!--端点取了名字 以及制定了bindingConfiguration-->
                <endpoint address=""
                          binding="basicHttpBinding" 
                          bindingConfiguration="newBasicHttpBinding"
                          name="basicHttpBinding_IMetadataExchange" 
                          contract="Wcf_Stream_Service.IMediaService">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
              <endpoint address=""  
                        binding="netTcpBinding"
                        bindingConfiguration="newNetTcpBinding"                        
                        name="NetTcpBinding_IMetadataExchange" 
                        contract="Wcf_Stream_Service.IMediaService" />
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8733/MediaService" />
                      <!--为tcp协议定义一个地址-->
                        <add baseAddress="net.tcp://localhost:8734/tcp" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>
</configuration>

最后是service类的main方法:

 1 using System;
 2 using System.ServiceModel;
 3 
 4 namespace Wcf_Stream_Service
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             ServiceHost host = new ServiceHost(typeof(MediaService));
11             host.Open();
12             Console.WriteLine("服务已经启动");
13             Console.ReadKey();
14         }
15     }
16 }

2 接下来是client

首先以管理员身份启动service,然后引用这个服务引用自动在配置文件中生成了对应的wcf服务配置

最后直接就是main方法

 1 using System;
 2 using System.IO;
 3 
 4 namespace Wcf_Stream_Client
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             ServiceReference_Stream.MediaServiceClient client = new ServiceReference_Stream.MediaServiceClient("NetTcpBinding_IMetadataExchange");
11             string mediaName=client.GetMediaList()[1];
12             Console.WriteLine(mediaName);
13 
14             Stream s = client.GetMedia(mediaName);
15             //var num = s.Length;
16             byte[] bytes = new byte[1000];
17             s.Read(bytes, 0, bytes.Length);
18             //s.Seek(0, SeekOrigin.Begin);
19 
20             FileStream fs = new FileStream("new_" + mediaName + ".txt", FileMode.Create);
21             BinaryWriter writer = new BinaryWriter(fs);
22             writer.Write(bytes);
23             writer.Close();
24             fs.Close();
25             Console.ReadKey();
26         }
27     }
28 }

 特别要备注的一点是:流传输并不是一定非要让接口请求的方法的返回值的Stream类型,什么类型都可以,只是他们在传输过程中会变成流,接收后按照协议栈又会从流转成方法返回值对应的类型。如果不按流传输,按buffer传输,我们也没有将返回值转成byte不是吗!

原文地址:https://www.cnblogs.com/wholeworld/p/10171837.html