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;
}