【问题标题】:Upload file using ftp使用ftp上传文件
【发布时间】:2014-09-11 06:50:57
【问题描述】:

我在 IIS 服务器上使用网站面板。 我想使用 ftp 上传文件

我使用了这个代码:

try
{
     WebClient webClient = new WebClient();

     OpenFileDialog fd = new OpenFileDialog();
     fd.ShowDialog();

     MessageBox.Show(fd.FileName);

     webClient.UploadFileTaskAsync(new Uri("ftp://" + "username" + ":" +"pass" +"@" + "address/" + "name.ext"), fd.FileName);

 }
 catch (Exception ex)
 { 
     MessageBox.Show(ex.Message);
 }

这段代码运行没有错误。当我使用网站面板的文件管理器时,创建了一个文件“Name.ext”,但该文件大小为 0 KB。为什么?我的问题是什么?!

我确信 Windows 防火墙允许我这样做。

更新:我正在使用 UploadFileTask 和 UploadFile(不同步)但结果与异步相同:(

【问题讨论】:

  • 查看我的代码,检查响应变量及其返回的内容。它可能包含您要查找的错误代码
  • 类似的问题,但不是异步方法。 *.com/questions/15268760/…

标签: c# .net ftp async-await


【解决方案1】:

我的第一个想法是您没有等待 Async 调用,因此运行此代码的任何进程或线程都可能在 UploadFileTaskAsync 调用实际完成之前结束。

尝试将 try 块的最后一次调用更改为

await webClient.UploadFileTaskAsync(new Uri("ftp://" + "username" + ":" +"pass" +"@" + "address/" + "name.ext"), fd.FileName);

您可能还想检查调用的返回值:

var result = await webClient.UploadFileTaskAsync(new Uri("ftp://" + "username" + ":" +"pass" +"@" + "address/" + "name.ext"), fd.FileName);

结果对象是来自服务器的响应的byte[]

【讨论】:

  • 一开始我也是这么想的,等了很久。并将其更改为 UploadFile (An Unasync) 但结果与 UploadFileTaskAsync 相同:(
【解决方案2】:

您的异常可能会被从WebClient.UploadFileTaskAsync 返回的未等待任务中吞没。你应该在你的任务上await,这样你的catch 块会检测到一个潜在的异常,因为它会传播到等待的代码行:

public async Task UploadFileByFtpAsync()
{
   try
   {
       WebClient webClient = new WebClient();

       OpenFileDialog fd = new OpenFileDialog();
       fd.ShowDialog();

       MessageBox.Show(fd.FileName);

       Task<byte[]> response = await webClient.UploadFileTaskAsync(new Uri("ftp://" + "username" + ":" +"pass" +"@" + "address/" + "name.ext"), fd.FileName);

       // You might want to validate the response status code is valid here
    }
    catch (Exception ex)
    { 
        MessageBox.Show(ex.Message);
        // Do useful exception handling here
    }
}

编辑

正如我在评论中所说,检查response 变量,它包含您的上传尝试可能失败的响应。

编辑 2

看来问题出在 web/ftp 请求的 KeepAlive 属性上。 The underlying connection was closed: The server committed a protocol violation. FTPhere 中有一个接受的答案

【讨论】:

  • 是的,我认为你是对的。这次它给出了一个错误“底层连接已关闭:服务器违反了协议。”并创建文件...是服务器错误吗?!我自己能解决吗?!
【解决方案3】:

我建议使用原生 FtpWebRequest 类来上传文件。

     try
     {
        OpenFileDialog fd = new OpenFileDialog();
        fd.ShowDialog();
        MessageBox.Show(fd.FileName);

        FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create("ftp://address/" + fd.FileName);
        request.Method = WebRequestMethods.Ftp.UploadFile;
        request.Credentials = new NetworkCredential("username", "pass");
        request.UsePassive = true;
        request.UseBinary = true;
        request.KeepAlive = false;

        FileStream stream = File.OpenRead(fd.FileName);
        byte[] buffer = new byte[stream.Length];

        stream.Read(buffer, 0, buffer.Length);
        stream.Close();

        Stream reqStream = request.GetRequestStream();
        reqStream.Write(buffer, 0, buffer.Length);
        reqStream.Close();
       }
    catch (Exception ex)
    { MessageBox.Show(ex.Message);


    }

【讨论】: