博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ESFramework Demo -- 简单的网络硬盘Demo
阅读量:7208 次
发布时间:2019-06-29

本文共 3222 字,大约阅读时间需要 10 分钟。

FTP服务器最核心的功能就是提供文件的上传、下载服务。在ESFramework Demo -- 文件传送Demo(附源码)一文中,我们演示了如何在客户端与客户端之间相互传送文件,现在我们就实现一个简单的FTP服务器,以演示如何在客户端与服务器之间传送文件。在阅读本文之前,请务必先掌握ESFramework 开发手册(03) -- 文件(夹)传送 一文中介绍的文件传送的流程及相关的API的用法。

本Demo主要演示以下功能:

(1)客户端浏览服务器默认目录下的所有文件。

(2)客户端上传文件到服务器的默认目录下。

(3)客户端可以下载服务器默认目录下任何一个文件。

一.定义信息类型

根据上面提到的功能需求,我们需要定义相应的信息类型:

复制代码

public static class FtpInformationTypes
{
/// <summary>
/// 获取所有文件名。C->S
/// </summary>
public const int GetAllFileNames = 0;
/// <summary>
/// 请求下载文件。C->S
/// </summary>
public const int DownloadFile = 1;
}
复制代码
上传文件就不用定义额外的信息类型了,可以直接使用IFileOutter的请求发送文件方法就可以了。

二.服务端

服务端将文件目录设定在运行目录下的"FileFold"文件夹,所有上传的文件都将被保存到这个目录,所有要下载的文件也来自这个目录。

服务端的CustomizeHandler类实现了自定义信息处理器接口ICustomizeHandler,当收到来自客户端的FtpInformationTypes.GetAllFileNames同步调用时,就将FileFold目录下的所有文件列表返回给客户端。当收到请求下载文件的信息时,就调用IFileController.BeginSendFile方法将指定的文件发给客户端。  当客户端要上传文件时,会直接调用IFileOutter的BeginSendFile,此时,服务端将触发IFileController的FileRequestReceived事件。所以,服务端需要预定并处理这个事件:

复制代码

void fileController_FileRequestReceived(string fileID, string senderID, string fileName, ulong fileLength, ESPlus.FileTransceiver.ResumedProjectItem resumedProjectItem, string comment)
{
int index = fileName.LastIndexOf('\');
string filePath = string.Format(@"{0}FileFold{1}", AppDomain.CurrentDomain.BaseDirectory, fileName.Substring(index +1));
this.fileController.BeginReceiveFile(fileID, filePath);
}
复制代码
服务端将保存文件的路径设定在FileFold目录下,然后调用IFileController.BeginReceiveFile方法开始接收文件。当然,这里的处理做了很多简化,比如没有判断磁盘空间是否足够、是否有同名文件等等。

三.客户端

客户端登录成功后,进入主界面。主界面初始化时,将向服务器发送FtpInformationTypes.GetAllFileNames同步调用,然后将返回的文件列表显示在ListView中。

双击ListView中的某个文件时,就向服务器发送FtpInformationTypes.DownloadFile信息。就像上面描述的一样,服务端就会调用IFileController.BeginSendFile方法发送指定的文件,然后,客户端也会触发IFileOutter.FileRequestReceived事件,处理这个事件时,我们让用户选择要存储的路径。

复制代码

void fileOutter_FileRequestReceived(string projectID, string senderID, string fileName, ulong totalSize, ResumedProjectItem resumedFileItem, string comment)
{
if (this.InvokeRequired)
{
this.Invoke(new CbReadyToAcceptFileAsyn(this.fileOutter_FileRequestReceived), projectID, senderID, fileName, totalSize, resumedFileItem, comment);
}
else
{
string savePath = ESBasic.Helpers.FileHelper.GetPathToSave("保存", fileName, null);
if (string.IsNullOrEmpty(savePath))
{
this.fileOutter.RejectFile(projectID);
}
else
{
this.fileOutter.BeginReceiveFile(projectID, savePath);
}
}
}
复制代码
如果用户取消了保存路径的选择,表示放弃下载文件,这样就调用IFileOutter.RejectFile来进行取消操作。
当客户端点击上传按钮时,就直接调用IFileOutter.BeginSendFile来准备上传文件。

复制代码

private void toolStripButton_upLoad_Click(object sender, EventArgs e)
{
string filePath = ESBasic.Helpers.FileHelper.GetFileToOpen("打开");
if (filePath == null)
{
return;
}
string fileID;
SendingFileParas sendingFileParas = new SendingFileParas(2048, 0);//文件数据包大小,可以根据网络状况设定,局网内可以设为204800,传输速度可以达到30M/s以上;公网建议设定为2048或4096或8192
this.fileOutter.BeginSendFile(NetServer.SystemUserID, filePath, null, sendingFileParas, out fileID);
}
复制代码
这将引发服务端IFileController的FileRequestReceived事件触发,然后,服务端会调用IFileController.BeginReceiveFile方法,从而启动文件的正式传递。

下图是客户端正在进行上传下载文件时的截图:          本文是一个最简单的演示文件上传下载功能的demo,非常的粗糙,仅仅用于示范如何使用ESPlus提供的文件传送功能在服务端和客户端之间传递文件。若要正式开发一个文件服务器系统,本文只能算是一个简陋的起点,还有很多复杂的事情要做,那已经超出了本文的内容,但你若有任何想法,欢迎与我们讨论。

转载于:https://blog.51cto.com/13284474/2175819

你可能感兴趣的文章
C/C++语言中的结构体对齐
查看>>
css基础
查看>>
平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】...
查看>>
如果类型是dynamic的且其属性也是dynamic的
查看>>
liinux 下mysql常用命令
查看>>
如何用SQL语句查询Excel数据?
查看>>
用js实现分页功能以及利用xml实现分页功能——数据岛
查看>>
《Programming in Lua 3》读书笔记(十九)
查看>>
html知识点总结
查看>>
博客园
查看>>
Three.js加载3D模型
查看>>
Basic: Fisher's transform
查看>>
mint-ui vue双向绑定
查看>>
Eclipse快捷键一览表(转载)
查看>>
随机访问流 RandomAccessFile
查看>>
图片上传读取代码
查看>>
服务器安装环境基本操作
查看>>
nslookup命令
查看>>
c++函数模板作为类的成员函数,编译报错LNK2019的解决方法
查看>>
Tensorflow安装
查看>>