南雄北北

导航

Windows 服务里使用Remoting技术监听 用 C#实现上传和下载功能

新建一个windows 服务

添加有关Remoting的引用:

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Serialization.Formatters;

using CommunitySystem_HESave;

然后分别在OnStart()、OnStop()函数里添加如下代码:

 protected override void OnStart(string[] args)
        {
            // TODO: 在此处添加代码以启动服务。
            StartServer();
        }

 

private void StartServer()
        {
            try
            {
               
                BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
                BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
                serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

                IDictionary props = new Hashtable();
                props["port"] = 5102;
                TcpChannel channel = new TcpChannel(props, clientProvider, serverProvider);
                ChannelServices.RegisterChannel(channel, false);

               //注册在使用Remoting时需要用到的方法代码

                RemotingConfiguration.RegisterWellKnownServiceType(
                               typeof(CommunitySystem_Save), "SaveFile",
                               WellKnownObjectMode.Singleton);
                RemotingConfiguration.RegisterWellKnownServiceType(
                               typeof(CommunitySystem_Save), "ReadFile",
                               WellKnownObjectMode.Singleton);
                RemotingConfiguration.RegisterWellKnownServiceType(
                              typeof(CommunitySystem_Save), "m_strGetFile",
                              WellKnownObjectMode.Singleton);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.Write(ex.Message);
                throw ex;
            }
        }

 

 protected override void OnStop()
        {
            // TODO: 在此处添加代码以执行停止服务所需的关闭操作。
            foreach (IChannel channel in ChannelServices.RegisteredChannels)
            {
                ChannelServices.UnregisterChannel(channel);
            }
        }

这个时候需要另外添加一个类去实现上面注册的方法,代码如下:

 public List<FileInfo> m_strGetFile(string m_strPath)
        {
            List<FileInfo> list = new List<FileInfo>();
            if (Directory.Exists(m_strPath))
            {
                foreach (string fileInfo in System.IO.Directory.GetFiles(m_strPath))
                {
                    FileInfo fi = new FileInfo(fileInfo);
                    list.Add(fi);
                }
            }
            return list;
        }

 public byte[] ReadFile(string file_path)
        {
            byte[] buffer = null;
            if (File.Exists(file_path))
            {
                FileStream stream = new FileStream(file_path, FileMode.Open, FileAccess.Read);
                int count = int.Parse(stream.Length.ToString());
                buffer = new byte[count];
                int num2 = stream.Read(buffer, 0, count);
                stream.Close();
                stream.Dispose();
                stream = null;
            }
            return buffer;
        }

public bool SaveFile(string file_path, byte[] file_data)
        {
            bool flag = false;
            try
            {
                string directoryName = Path.GetDirectoryName(file_path);
                if (directoryName.Length == 0 || file_data ==null)
                {
                    return false;
                }
                string fileName = Path.GetFileName(file_path);
                if (!Directory.Exists(directoryName))
                {
                    DirectoryInfo info = Directory.CreateDirectory(directoryName);
                }
                FileStream stream = new FileStream(file_path, FileMode.Create);
                if (stream != null)
                {
                    stream.Write(file_data, 0, file_data.GetLength(0));
                    stream.Close();
                    flag = true;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.Write(ex.Message);
                throw ex;
            }
            return flag;
        }

好,到目前为止 服务器端的代码就写好了。

下面给出客户端的实现上传下载的代码

新建一个类,用于注册客户端

   public  class ScuFileService
    {
        public ScuFileService()
        {
            _scp_location = "tcp://localhost:5102/SaveFile";
        }
        public bool SaveFile(string relative_path, byte[] data)
        {
            bool ret = false;
            return ret;
        }
        public bool InitService()
        {
            ChannelServices.RegisterChannel(new TcpChannel(), false);
            return true;
        }
       public CommunitySystem_Save GetScp()
        {
            CommunitySystem_Save rcv = (CommunitySystem_Save)Activator.GetObject(typeof(CommunitySystem_Save),
                _scp_location);
            return rcv;
        }
        public string ScpLocation
        {
            get { return _scp_location; }
            set { _scp_location = value; }
        }
        private string _scp_location;
    }

上传:

 

OpenFileDialog m_OpenFile = new OpenFileDialog();
             m_OpenFile.Filter = "所有文件(*.*)|*.*";
             m_OpenFile.Multiselect = true;
             if (m_OpenFile.ShowDialog() == DialogResult.OK)
             {
                 List<string> m_strFileNameList = new List<string>();
                 foreach (string filenames in m_OpenFile.FileNames)
                 {
                     m_strFileNameList.Add(filenames);
                 }
                 if (m_strFileNameList.Count < 0)
                     return;
                 XmlDocument document = new XmlDocument();

                //获取配置文档LoginFile.xml中的服务器地址配置
                 string strFilePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                 document.Load(strFilePath + @"\LoginFile.xml");
                 XmlElement element = document["Main"]["CSServers"];
                 if (null != element)
                 {
                     int intCount = element.ChildNodes.Count;
                     if (intCount > 0)
                     {
                         bool ret = false;
                         for (int i = 0; i < intCount; i++)
                         {
                             string strFileServerIP = element.ChildNodes[i].InnerText.Trim();

                             //注册客户端中的服务
                             ScuFileService _scu = new ScuFileService();
                             string dst = "tcp://" + strFileServerIP + ":5102/SaveFile";
                             _scu.ScpLocation = dst;
                             CommunitySystem_Save rcv = _scu.GetScp();

                             if (rcv != null)
                             {
                                 string resultFile = m_strFileToServicePath() + m_strFileName + "\\";
                                 for (int intI = 0; intI < m_strFileNameList.Count; intI++)
                                 {
                                    string m_stresultFile = resultFile + Path.GetFileName(m_strFileNameList[intI]);
                                    ret = rcv.SaveFile(m_stresultFile, ReadFile(m_strFileNameList[intI]));
                                 }
                             }
                             if (ret)
                             {
                                 MessageBox.Show("恭喜您成功提交附件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                             }
                             else
                             {
                                 MessageBox.Show("提交附件失败,请检查原因:\r\n 1.检查LoginFile配置是否正确。\r\n 2.检查服务器是否安装了上传服务。\r\n 3.检查客户端是否能正确访问指定服务器。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                             }
                         }
                     }
                 }
             }

下载:

   m_objList = m_btGetFile(date,Seqid, m_strFileName, out m_lstFileName);
            if (m_objList.Count < 0)
            {
                MessageBox.Show("没有上传附件,请重新上传!!");
                return;
            }
            FolderBrowserDialog m_objSavePath = new FolderBrowserDialog();
            m_objSavePath.RootFolder = Environment.SpecialFolder.MyComputer;
            m_objSavePath.Description = com.digitalwave.GUI_Base.frmMDI_Child_Base.CurrentLoginInfo.m_strEmpName + "您好,请选择保存文件的路径";
            if (m_objSavePath.ShowDialog() == DialogResult.OK)
            {
                string strPath = m_objSavePath.SelectedPath + "\\" + date + "\\" + Seqid + "\\" + m_strFileName + "\\";
                bool m_blnGet = false;
                for (int intI = 0; intI < m_objList.Count; intI++)
                {
                    fileName = Path.GetFileName(m_lstFileName[intI]);
                    string strSavePath = strPath + fileName;
                    m_blnGet = SaveFile(strSavePath, m_objList[intI]);
                }
                if (m_blnGet)
                {
                    MessageBox.Show("恭喜下载成功!/n 保存路径:" + strPath + "");
                }
            }

 internal List<byte[]> m_btGetFile(string date,string Seqid, string m_strFileName, out List<string> p_strPath)
        {
            byte[] objFile = null;
            p_strPath = new List<string>();
            List<byte[]> fileList = new List<byte[]>();
            List<string> m_strPath = new List<string>();

             XmlDocument document = new XmlDocument();
             string strFilePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
             document.Load(strFilePath + @"\LoginFile.xml");
             XmlElement element = document["Main"]["CSServers"];
             if (null != element)
             {
                 int intCount = element.ChildNodes.Count;
                 if (intCount > 0)
                 {
                     for (int i = 0; i < intCount; i++)
                     {
                         string strFileServerIP = element.ChildNodes[i].InnerText.Trim();
                         ScuFileService _scu = new ScuFileService();
                         string dst = "tcp://" + strFileServerIP + ":5102/m_strGetFile";
                         _scu.ScpLocation = dst;
                         CommunitySystem_Save rcv = _scu.GetScp();

                         if (rcv != null)
                         {
                             string m_strPathName = "d:\\CommuintySystemSave\\" + date + "\\" + Seqid + "\\" + m_strFileName + "\\";
                             List<FileInfo> files = rcv.m_strGetFile(m_strPathName);
                             if (files.Count > 0)
                             {
                                 string dstread = "tcp://" + strFileServerIP + ":5102/ReadFile";
                                 _scu.ScpLocation = dstread;
                                 CommunitySystem_Save rcvs = _scu.GetScp();

                                 for (int intI = 0; intI < files.Count; intI++)
                                 {
                                     objFile = rcvs.ReadFile(files[intI].FullName);
                                     p_strPath.Add(files[intI].FullName);
                                     fileList.Add(objFile);
                                 }
                             }
                             else
                             {
                                 MessageBox.Show("No Files!");
                             }
                         }
                     }
                 }
             }
             return fileList;
        }

到此这个服务的关键代码已经给出,基本上可以实现标题的功能,当然这个方法还有一些可以改进的地方,比如说上传的文件过大的时候可能会导致本地读文件时死机的情况,在这样的情况下,我们可以使用后台进程或者线程去做读文件的操作。这样可以不影响到界面的其他操作。

posted on 2010-08-20 15:26  南雄北北  阅读(1195)  评论(0编辑  收藏  举报