zoukankan      html  css  js  c++  java
  • WCF实现上传图片功能

    初次学习实现WCF winform程序的通信,主要功能是实现图片的传输。

    下面是实现步骤:

    第一步:

    首先建立一个类库项目TransferPicLib,导入wcf需要的引用System.ServiceModel,建立接口ITransferPicService,建立类文件TransferPicService实现ITransferPicService接口。

    代码:ITransferPicService

    ITransferPicService
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.ServiceModel;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace TransferPicLib
    {
        [ServiceContract]
        public interface ITransferPicService
        {
            [OperationContract]//操作契约
            Stream GetPic();
            [OperationContract]
            void SendPic(Stream transferPic);
        }
     
    }
    

    代码:TransferPicService

    TransferPicService
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace TransferPicLib
    {
        public class TransferPicService : ITransferPicService
        {
            public static Stream PicSource = new MemoryStream();
    
            /// <summary>
            /// 从服务端下载图片到本地 (上传和下载都是拷贝的过程)
            /// </summary>
            /// <returns></returns>
            public Stream GetPic()
            {
                MemoryStream ms = new MemoryStream();
                PicSource.Position = 0;//指明从第0位开始拷贝
                PicSource.CopyTo(ms);//服务端将客户端的Stream复制一份
                ms.Position = 0;//注意如果缺少该条代码接收端将无法显示上传图片
                return ms;//然后在返回客户端;
            }
    
            /// <summary>
            /// 从客户端上传图片到服务端(将客户端的Stream拷贝给服务端的Stream)
            /// </summary>
            /// <param name="transferPic"></param>
            public void SendPic(Stream transferPic)
            {
                PicSource.Position = 0;
                transferPic.CopyTo(PicSource);
            }
        }
    }
    这里要使用到app.config配置文件,可以通过建立wcf服务类库生成的模板,直接复制过来,修改所需的参数。
    代码:app.config
    App.config
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" />
      </system.web>
      <!-- 部署服务库项目时,必须将配置文件的内容添加到 
      主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
      <system.serviceModel>
        <services>
          <service name="TransferPicLib.TransferPicService">
            <host>
              <baseAddresses>
                <add baseAddress = "http://localhost:8100/transferPic" />
              </baseAddresses>
            </host>
            <!-- Service Endpoints -->
            <!-- 除非完全限定,否则地址将与上面提供的基址相关 -->
            <endpoint address="" binding="basicHttpBinding" contract="TransferPicLib.ITransferPicService">
              <!-- 
                  部署时,应删除或替换下列标识元素,以反映
                 用来运行所部署服务的标识。删除之后,WCF 将
                  自动推断相应标识。
              -->
              <identity>
                <dns value="localhost"/>
              </identity>
            </endpoint>
            <!-- Metadata Endpoints -->
            <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 --> 
            <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- 为避免泄漏元数据信息,
              请在部署前将以下值设置为 false -->
              <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
              <!-- 要接收故障异常详细信息以进行调试,
              请将以下值设置为 true。在部署前设置为 false 
                以避免泄漏异常信息-->
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    
    </configuration>
    

     

    第二步:

    创建一个控制台程序TransferPicHoset,这个程序主要是启动wcf服务。项目建立完成后首先添加TransferPicLib的引用和using System.ServiceModel的引用。

    代码:Program

    Program
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using System.Text;
    using System.Threading.Tasks;
    using TransferPicLib;
    namespace TransferPicHose
    {
        class Program
        {
            static void Main(string[] args)
            {
                NetTcpBinding bind = new NetTcpBinding();
                bind.MaxBufferSize = 214783647;
                bind.TransferMode = TransferMode.Streamed;
                bind.MaxReceivedMessageSize = 214783647;
                bind.Security.Mode = SecurityMode.None;
                //超出using 范围程序会自动释放
                using (ServiceHost host = new ServiceHost(typeof(TransferPicLib.TransferPicService)))
                {
                    host.AddServiceEndpoint(typeof(ITransferPicService), bind, "net.tcp://localhost:8100/transferPic");//该地址为宿主地址,和客户端接收端地址保持一致
                    if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                    {
                        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                        behavior.HttpGetEnabled = true;
                        behavior.HttpGetUrl = new Uri("http://localhost:8103/transferPic/metadata/");
                        host.Description.Behaviors.Add(behavior);
                    }
                    host.Opened += delegate { Console.WriteLine("图片程序已成功启动!"); };
                    host.Open();
                    Console.ReadLine();
                }
            }
        }
    }
    

    此刻如果第一步的配置文件没问题,服务就可以启动了,我在做实验的时候,遇到了地址找不到的错误,最后发现是端口配置错误了,通过看官方的demo发现做wcf程序启动visual studio 需要以管理员的身份启动。暂时不知道为什么要以管理员身启动,不过没什么影响。

    现在服务已经完成了,下面我们就可以创建图片上传端与接收端了,这里先建立图片上传项目吧

    第三步:

    创建一个winform项目winFormUploadDemo,这个窗体主要是实现选择图片,上传图片功能。首先要添加TransferPicLib的引用和using System.ServiceModel的引用

    界面布局如下:

    image

    代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.ServiceModel;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using TransferPicLib;
    namespace winFormUploadDemo
    {
        public partial class UploadForm : Form
        {
            string fileName = "";
            public UploadForm()
            {
                InitializeComponent();
            }
    
            private void btnBrowser_Click(object sender, EventArgs e)
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                if(openFileDialog.ShowDialog()==DialogResult.OK)
                {
                    fileName = openFileDialog.FileName;
                    txtPicName.Text = fileName;
                    pictureBox1.Load(fileName);
                }else
                {
                    return;
                }
            }
    
            private void btnUpload_Click(object sender, EventArgs e)
            {
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                Stream sm = new MemoryStream();
                fs.Position = 0;
                fs.CopyTo(sm);
                //拷贝完成之后进行上传
    
                EndpointAddress epAddr = new EndpointAddress("net.tcp://localhost:8100/transferPic");//此处也可以用IIS做服务
                NetTcpBinding bind = new NetTcpBinding();//绑定方式
                bind.MaxBufferPoolSize = 2147483647;//最大缓冲
                bind.TransferMode = TransferMode.Streamed;//传输模式为流式处理
                bind.MaxReceivedMessageSize = 2147483647;//定义了服务端接收Message的最大长度,防止文件过大
                bind.Security.Mode = SecurityMode.None;//安全模式设置为不进行验证;
                //创建一个工厂
                ITransferPicService proxy = ChannelFactory<ITransferPicService>.CreateChannel(bind, epAddr);
                sm.Position = 0;
                proxy.SendPic(sm);//WCF客户端调用该方法 把客户端sm上传到服务端去;
            }
        }
    }
    

    此时,图片选择与上传功能就实现了。下面我们创建接收端程序

    第四步:

    界面如下:窗体上添加一个picturebox用来展示接收到的图片

    image

    记得添加TransferPicLib的引用和using System.ServiceModel的引用

    代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.ServiceModel;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using TransferPicLib;
    namespace WinFormReceiver
    {
        public partial class ReceivedForm : Form
        {
            public ReceivedForm()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                Thread myThread = new Thread(ShowPic);//创建一个线程
                myThread.IsBackground = true;//设置后台线程(防止主程序关闭后,仍在运行)
                myThread.Start();//启动线程
            }
            public void ShowPic()
            {
                #region 同客户端一样,创建WCF客户端
    
                EndpointAddress epAddr = new EndpointAddress("net.tcp://localhost:8100/transferPic");
                NetTcpBinding bind = new NetTcpBinding();
                bind.MaxBufferPoolSize = 2147483647;
                bind.TransferMode = TransferMode.Streamed;
                bind.MaxReceivedMessageSize = 2147483647;
                bind.Security.Mode = SecurityMode.None;
                //创建一个通道
                ITransferPicService proxy = ChannelFactory<ITransferPicService>.CreateChannel(bind, epAddr);
    
                #endregion
    
                while (true)
                {
                    Stream streamFromServer = proxy.GetPic(); //返回一个文件流;
                    MemoryStream ms = new MemoryStream();//滤层流拷贝一份;
                    ms.Position = 0;
                    streamFromServer.CopyTo(ms);//将该文件流拷贝给到ms;
                    if (ms.Length == 0)
                    {
                        System.Threading.Thread.Sleep(300);//300百毫秒执行一次;
                        continue;
                    }
                    Bitmap tn = new Bitmap(ms);//创建一个位图;把ms变成图片;
                    pictureBox1.Image = tn;
    
                    System.Threading.Thread.Sleep(300);//300百毫秒执行一次;Sleep表示当前线程挂起指定的时间;
                }
            }
        }
    }
    这里我们的代码就完成了

     

    第五步

    测试启动我们的项目。

    四、运行程序。
    1、打开TransferPicHost 文件中bin目录,启动“TransferPicHost.exe”,此时会弹出一个控制台应用程序的窗体,并提示“图片功能已成功启动!”。
    2、分别启动发送端和接收端项目程序;
    (将“WinFormClient” 或者 “WinFormReceiver” 设为启动项目,并启动另一个项目文件夹bin目录下的“WinFormReceiver.exe”或者“WinFormClient.exe”)
    点击发送端“浏览按钮” 进行选择图片,之后点击“上传按钮”。这时,你会发现客户端上传的图片显示在了接收端的窗体上。程序运行成功。

    源码地址:https://github.com/dearbeans/Test.git

  • 相关阅读:
    Asp.net中利用ExecuteNonQuery()执行存储过程返回1解决方案
    在workflow中,无法为实例 ID“...”传递接口类型“...”上的事件“...” 问题的解决方法。
    jquery获取一个table中的一行的每个td的内容
    自动ping博客服务程序
    总结JavaScript(Iframe、window.open、window.showModalDialog)父窗口与子窗口之间的操作
    sql server try...catch使用
    IAsyncResult异步设计
    jquery 判断一个对象是否存在
    数据库表扩展字段设计思路
    REST接口POST方法发送文件到服务器(C#)
  • 原文地址:https://www.cnblogs.com/dearbeans/p/6033279.html
Copyright © 2011-2022 走看看