c# - 如何在后台下载 FTPES 密码保护文件
问题描述
在过去的几周里,我一直在搞砸很多事情,似乎找不到正确的方法。我在 Unity 中这样做,但当然本质应该可以在环境。
我在 FTPES 上有 3 个音频文件和一个文本文档,要通过 FTP 清除显式 TLS:
我已使用以下代码成功登录以验证文件是否存在:
WebRequest.RegisterPrefix("ftps", new FtpsWebRequestCreator());
ftpRequest = (FtpWebRequest)WebRequest.Create("ftps://" + IP + "/" + fileEndPath);
ftpRequest.Credentials = new NetworkCredential(User, Password);
ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateCertificate);
ServicePointManager.Expect100Continue = true;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
ValidConnection = true;[/code]
话虽如此,我也通过多种方式成功下载了该文件。我遇到的问题如下:
使用 FtpWebRequest 我可以下载文件,并且曾经能够将文件作为 AudioClip 加载(老实说,我不知道为什么它会随机停止工作,使用 ftpwebrequest 下载是......)使用 WWW 类,但是因为我可以似乎没有找到将它推到后台的方法。我尝试使用streamWriter写入文件,但它似乎没有用。
使用 UnityWebRequest 我无法登录 FTPS 服务器,因为它是为基于 HTTP 的通信而设计的。
使用 WebClient 我能够登录到服务器(通过注册如上所示的前缀并将其在低级别与 useSsl bool 设置为 true 相关联)和
- 使用 .DownloadFile 无法下载文件,会挂起 Unity 主线程。
- 使用 .DownloadFileAsyn 可以下载文件,但没有读取权限,并且 Complete 事件永远不会被调用以继续使用 WWW 加载文件。
我在这篇文章中使用的是 WebClient.DownloadFileAsyn:
internal void Download(FileType fileType)
{
IsDownloading = true;
if (ValidConnection)
{
try
{
StartCoroutine(SetFileCreation());
using (WebClient client = new WebClient())
{
WebRequest.RegisterPrefix("ftps", new FtpsWebRequestCreator());
client.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadFileProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCompleted);
client.DownloadFileAsync(ftpIP, Application.dataPath + "/StreamingAssets/" + ftpFilePath, fileType);
}
}
catch (WebException ex)
{
Debug.LogError(ex.Message + ex.StackTrace + "\n");
}
}
else
IsDownloading = false;
}
设置文件创建();是一种验证位置的方法,如果存在,则覆盖,否则在继续之前创建目录。
现在我没有任何干净的代码(除了我所展示的)来展示我一直在做的事情,但是如果有人可以指出我的一个很好的例子,(我还没有找到很多关于从 Unity 中的 FTPS 下载的内容)或只是分享他们如何从头开始解决这个问题,我们将不胜感激。
附带说明一下,我知道我的 FTP 服务器通过https://ftptest.net/按预期运行 我的服务器日志(我自己托管它,所以我可以完全控制设置)显示所有正确的消息,直到RETR 和传输成功消息。
我看过很多关于 FTPS 的帖子,关于 Unity 内部和外部的各种下载方式,所有不同级别的网络通信;高级和低级,以及如何将文件夹中的文件实时加载到 Unity 中。但是没有什么可以将这一切合二为一,又好又干净。吻!
和我们大多数人一样,我要关注更大的图景,不能让这个细节继续延迟开发。
编辑(服务器日志):
这是来自我的 WebClient.DownloadAsync() 的服务器日志;
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> Connected, sending welcome message...
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> AUTH TLS
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> 234 Using authentication type TLS
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> SSL connection established
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> PBSZ 0
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> 200 PBSZ=0
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> PROT P
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> 200 Protection level set to P
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> USER Test
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> 331 Password required for test
(000657)08/23/2018 22:51:32 - (not logged in) ([MyIP])> PASS ********
(000657)08/23/2018 22:51:32 - test ([MyIP])> 230 Logged on
(000657)08/23/2018 22:51:32 - test ([MyIP])> OPTS utf8 on
(000657)08/23/2018 22:51:32 - test ([MyIP])> 200 UTF8 mode enabled
(000657)08/23/2018 22:51:32 - test ([MyIP])> PWD
(000657)08/23/2018 22:51:32 - test ([MyIP])> 257 "/" is current directory.
(000657)08/23/2018 22:51:32 - test ([MyIP])> CWD /
(000657)08/23/2018 22:51:32 - test ([MyIP])> 250 CWD successful. "/" is current directory.
(000657)08/23/2018 22:51:32 - test ([MyIP])> TYPE I
(000657)08/23/2018 22:51:32 - test ([MyIP])> 200 Type set to I
(000657)08/23/2018 22:51:32 - test ([MyIP])> PASV
(000657)08/23/2018 22:51:32 - test ([MyIP])> 227 Entering Passive Mode ([MyIP],195,146)
(000657)08/23/2018 22:51:32 - test ([MyIP])> RETR MainQuests.txt
(000657)08/23/2018 22:51:32 - test ([MyIP])> 150 Connection accepted
(000657)08/23/2018 22:51:32 - test ([MyIP])> SSL connection for data connection established
(000657)08/23/2018 22:51:32 - test ([MyIP])> 226 Transfer OK
值得注意的是,连接是保持的..它不会关闭,因为连接设置为文件下载完成后关闭......
这是我在使用 C# 任务时得到的日志,如Dan Flanagan的示例中所示:
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> Connected, sending welcome message...
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> AUTH TLS
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> 234 Using authentication type TLS
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> SSL connection established
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> PBSZ 0
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> 200 PBSZ=0
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> PROT P
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> 200 Protection level set to P
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> USER Test
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> 331 Password required for test
(000659)08/23/2018 22:58:10 - (not logged in) ([MyIP])> PASS ********
(000659)08/23/2018 22:58:10 - test ([MyIP])> 230 Logged on
(000659)08/23/2018 22:58:10 - test ([MyIP])> OPTS utf8 on
(000659)08/23/2018 22:58:10 - test ([MyIP])> 200 UTF8 mode enabled
(000659)08/23/2018 22:58:10 - test ([MyIP])> PWD
(000659)08/23/2018 22:58:10 - test ([MyIP])> 257 "/" is current directory.
(000659)08/23/2018 22:58:10 - test ([MyIP])> CWD /
(000659)08/23/2018 22:58:10 - test ([MyIP])> 250 CWD successful. "/" is current directory.
(000659)08/23/2018 22:58:10 - test ([MyIP])> TYPE I
(000659)08/23/2018 22:58:10 - test ([MyIP])> 200 Type set to I
(000659)08/23/2018 22:58:10 - test ([MyIP])> PASV
(000659)08/23/2018 22:58:10 - test ([MyIP])> 227 Entering Passive Mode ([MyIP],195,147)
(000659)08/23/2018 22:58:10 - test ([MyIP])> RETR MainQuests.txt
(000659)08/23/2018 22:58:10 - test ([MyIP])> 150 Connection accepted
(000659)08/23/2018 22:58:10 - test ([MyIP])> SSL connection for data connection established
(000659)08/23/2018 22:58:10 - test ([MyIP])> 426 Connection closed; transfer aborted. (000659)08/23/2018 22:58:10 - test ([MyIP])> QUIT
(000659)08/23/2018 22:58:10 - test ([MyIP])> 221 Goodbye
(000659)08/23/2018 22:58:10 - test ([MyIP])> disconnected.
解决方案
我删除了我在 Unity 中为你工作的旧 FTP 下载器脚本。您可能希望将文件保存在 Streaming Assets 文件夹中。不过,这应该对您有所帮助。我用它来下载他们从 StreamingAssets 文件夹播放的视频,但下载器确实有效。
using System;
using System.Threading.Tasks;
using System.IO;
using System.Net;
public class FTPDownloader : MonoBehaviour
{
public bool editorDownload;
public string savePath;
public string saveDir;
public string username;
public string pswd;
public void StartDownload(string serverIP, string serverFolder, string fileName)
{
string url = string.Format("{0}{1}{2}{3}", "ftp://", serverIP, serverFolder, fileName);
Task task = new Task(() =>
{
Download(url, fileName);
});
task.Start();
}
void Download(string url, string fileName)
{
if (!editorDownload)
{
return;
}
string path = Path.Combine(saveDir, fileName);
try
{
if(File.Exists(path))
{
//already downloaded
return;
}
//Debug.Log(url);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential(username, pswd);
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(path))
{
byte[] buffer = new byte[10240];
int read;
int total = 0;
while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, read);
total += read;
}
}
}
catch (Exception e)
{
if (File.Exists(path))
{
File.Delete(path);
}
//Debug.Log(e.ToString());
}
}
}
推荐阅读
- swift - Swift UI NSUbiquitousKeyValueStore 直到下次启动才会更新
- c# - 将引用 .net 核心库添加到 uwp 应用程序
- php - 根据数组中找到的 ID 运行 wp_query
- azure - Maven 构建任务因“JavaScript 堆内存不足”而失败
- r - 在R中使用时间序列数据中的坐标查找最近的相邻首都
- database - Docker 仍然在重建时删除数据库
- java - 当我拥有 All Args 构造函数时,我应该永远不要在 Spring Boot 中使用 @PostConstruct 吗?
- sql - 如何使我的购物车表在 postgress 中正常工作?
- amazon-web-services - 来自外部 Web 应用程序的 AWS IoT 设备管理?
- javascript - 使用 useMediaQuery 进行 Chakra ui 单元测试