初次学习实现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的引用

界面布局如下:

代码:

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用来展示接收到的图片

记得添加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

WCF实现上传图片功能的更多相关文章

  1. MVC ueditor的使用(实现上传图片功能)

    之前使用ckeditor不能实现上传图片功能,只要是我不知道怎么使用啦o( ̄ε ̄*),然后就换了ueditor~~,可以实现上传图片功能啦~\(≧▽≦)/~~ 下面是我的步骤:去官网下载最新版uedi ...

  2. aspx页面中用Input 标签实现上传图片功能

    实现上传图片功能需单独的建立一个aspx页面, 其中前台页面需要注意两点: a)实现上传功能的input的type="file" b)设置请求报文头为 enctype=" ...

  3. sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)

    sql server 关于表中只增标识问题   由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...

  4. JAVA 上传图片功能

    前后端实现上传图片功能(JAVA代码) 1.前端大概 请求头必须为AJAX请求头: 'X-Requested-With': 'XMLHttpRequest' 一般是指网页中存在的Content-Typ ...

  5. Vue实现上传图片功能

    前言: 用vue实现上传图片功能,效果图如下: 先说文件上传控件样式美化怎么做,我有两种方法. 1.先上代码 html部分: <div class="pics-wrapper" ...

  6. 配置Django-TinyMCE组件支持上传图片功能

    Django自带的Admin后台,好用,TinyMCE作为富文本编辑器,也蛮好用的,这两者结合起来在做博客的时候很方便(当然博客可能更适合用Markdown来写),但是Django-TinyMCE这个 ...

  7. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

  8. 富文本文件CKEDITOR增加上传图片功能(.net)

    如题,本身的CKEDITOR控件并没有开启上传图片的功能, 打开图像按钮,只有图像信息和高级两个table选项卡,版本不同,显示略有差异,我的实现是有两种方法都可以添加上传功能, 第一种方法使用CKE ...

  9. 使用.Net Core+IView+Vue集成上传图片功能

    最近的项目里有上传图片的功能,当然这个功能在项目里是必须要有的,那么目前这个项目是使用完全的前后端分离,在选择文件上传的组件中还是选择了全面支持Vue的IView,任何上传图片都是通过HTTP请求,服 ...

随机推荐

  1. mysql 故障整理(2)

    导入备份数据时报错. mysql> system mysql -uroot -p < /root/mingongge_bak.sqlEnter password: ERROR 1840 ( ...

  2. hdu 3371(启发式合并的最小生成树)

    Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  3. Cannot read property 'field' of undefined (at _8 (jquery.numberbox.js:33))

    问题描述: 页面端用了easyui的numberbox属性,然后在用js的方法修改值的时候,明明看到页面中的值是数字型(数量字段), 但是就是会报错 这种错误真的是很难理解,不过经过我的debug跟了 ...

  4. 如何让IE7,IE8支持css3

    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 原理:在用ie浏览 ...

  5. 51nod 1413 权势二进制【进制思维】

    1413 权势二进制 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 一个十进制整数被叫做权势二进制,当他的十进制 ...

  6. java trim start end space

    Java program that trims starts and ends public class Program { public static String trimEnd(String v ...

  7. RMI,socket,rpc,hessian,http比较

    SOCKET使用时可以指定协议TCP,UDP等: RIM使用JRMP协议,JRMP又是基于TCP/IP: RPC底层使用SOCKET接口,定义了一套远程调用方法: HTTP是建立在TCP上,不是使用S ...

  8. 一致性hash-java实现treemap版

    把不同号段的数据储存在不同的机器上,以用来分散压力.假如我们有一百万个QQ号,十台机器,,如何划分呢? 最简单粗暴的方法是用QQ号直接对10求余,结果为0-9 分别对应上面的十台机器.比如QQ号为 2 ...

  9. Redis(二)linux下redis安装

    上篇讲解了redis在windows下的安装,接下来看看在linux下如何安装redis(纯菜鸟入门级别)? (1)redis的下载及编译 这里,首先进入存放文件目录(我的云服务器的是:cd /jel ...

  10. MySQL索引,如何正确创建MySQL索引?

    索引可以提高数据的检索效率,也可以降低数据库的IO成本,并且索引还可以降低数据库的排序成本.排序分组操作主要消耗的就是CPU资源和内存,所以能够在排序分组操作中好好的利用索引将会极大地降低CPU资源的 ...