功能介绍:

主要是使用wcf框架实现从客户端上传图片到服务端并在服务端显示的基本功能。

一、首先创建两windows窗体应用程序“winformclient”(客户端、发送端)和“winformreceiver”(接收端)

1、如图设计formclient(发送端窗体)的界面,上边是一个panel容器中添加了一个textbox和 两个button,下边是一个picturebox控件(用于浏览上传之前的图片)。

 

 

然后添加浏览按钮下的后台代码,实现客户端浏览的功能。
  view code
 
 string filename = “”;//定义一个全局变量;
        //浏览选择上传内容
        private void btnbrowser_click(object sender, eventargs e)
        {

            //string filename = “”;//定义一个字段用于获取上传的文件名;
            openfiledialog openfiledialog = new openfiledialog();//创建一个openfiledialog对象专门用于打开文件
            if (openfiledialog.showdialog() == dialogresult.ok)//打开的文件对话框如果选择了ok按钮(确定),则为真,执行大括号中的内容
            {
                filename = openfiledialog.filename;
                txtpicname.text = filename;//在textbox中显示文件名
                picturebox1.load(filename);//使该图片在客户端pictubox中显示
            }
            else
                return;//未选中文件则返回;
        }
 
将winfomclient设为启动项目,运行
当你选择图片后,该图片会显示在发送端的窗体中,供发送者浏览,如需更改上传图片可重新选取,该图片将会被覆盖掉。(上传功能将在下文实现)
2、formreceiver接收端的窗体只需添加一个picturebox控件,用于显示客户端上传的图片。
二、在解决方案中添加两个类库:itransferpic(接口)、transferpic(继承接口),一个控制台应用程序 transferpichost(宿主程序);
该实例采用的是“自身托管宿主”并非“iis宿主”。
1、itransferpic
(1)、添加引用:using system.servicemodel;   using system.io;
(2)、创建一个“itransferpicservice”接口
  view code
 
[servicecontract]
    public interface itransferpicservice
    {
        [operationcontract]//操作契约
        stream getpic();
        [operationcontract]
        void sendpic(stream transferpic);
    }
 
 
2、transferpic
(1)、添加引用:using itransferpic;  using system.io;
(2)、创建一个“transferpicservice” 类,继承接口“itransferpicservice”并实现该接口;
  view code
 
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);
        }
    }
 
 
3、transferpichose
自身托管宿主: 利用wcf提供的servicehost<t>提供的open()和close()方法,可以便于开发者在控制台应用程序,windows应用程序乃至于asp.net应用程序中托管服务。不管自宿主的环境是何种应用程序,实质上托管服务的方式都是一致的。如该实例中用到的代码部分:
添加引用:
using system.servicemodel;
using itransferpic;
using system.servicemodel.description;
  view code
 
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(transferpic.transferpicservice)))
            {
                host.addserviceendpoint(typeof(itransferpicservice), bind, “net.tcp://localhost:9600/transferpic”);//该地址为宿主地址,和客户端接收端地址保持一致
                if (host.description.behaviors.find<servicemetadatabehavior>() == null)
                {
                    servicemetadatabehavior behavior = new servicemetadatabehavior();
                    behavior.httpgetenabled = true;
                    behavior.httpgeturl = new uri(“http://localhost:9603/transferpic/metadata/”);
                    host.description.behaviors.add(behavior);

                }

                host.opened += delegate { console.writeline(“图片程序已成功启动!”); };
                host.open();
                console.readline();
            }
        }
      
    }
 
三、实现上传。
1、winformclient 后台上传按钮部分;
添加引用:
using system.io;
using system.servicemodel;
using itransferpic;
  view code
 
//执行上传功能
        private void btnupload_click(object sender, eventargs e)
        {
            //picturebox1.load(filename);

            //读取流,上传文件流到服务器
            filestream fs = new filestream(filename, filemode.open, fileaccess.read);//创建一个文件,并把文件放在文件流里边;
            stream sm = new memorystream();//创建一个滤层流 将文件从第0位拷贝到sm中
            fs.position = 0;//获取或设置此流的当前位置
            fs.copyto(sm);
            //拷贝完成之后进行上传

            endpointaddress epaddr = new endpointaddress(“net.tcp://localhost:9600/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上传到服务端去;
        }
 
2、winformreceiver 后台。
添加引用:
using itransferpic;
using system.io;
using system.servicemodel;
  view code
 
 private void formreceiver_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:9600/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”)
点击发送端“浏览按钮” 进行选择图片,之后点击“上传按钮”。这时,你会发现客户端上传的图片显示在了接收端的窗体上。程序运行成功。
 

 
摘自 shang0109