【问题标题】:C# FtpWebRequest fails and throws an exception when it succeedsC# FtpWebRequest 失败,成功时抛出异常
【发布时间】:2020-12-23 16:07:43
【问题描述】:

标题似乎矛盾?继续阅读...

我正在尝试使用 FtpWebRequest 列出 FTP 服务器上的文件夹。

当我列出一个文件夹“myserver.whatever.com/folder”时它成功了。

当我列出一个嵌套文件夹时,“myserver.whatever.com/folder/folder1”它失败了。除了它抛出一个告诉我它成功的异常。

具体来说,这段代码:

request = (FtpWebRequest)WebRequest.Create(m_server + folder);
request.ClientCertificates = m_certificates;
request.Credentials = new NetworkCredential(m_userName.Normalize(), password.Normalize() );
request.EnableSsl = true;
request.Method = WebRequestMethods.Ftp.ListDirectory;
response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);

抛出此异常:

The remote server returned an error: 150 Opening data connection. List started\r\n

微软不知道 150 的代码不是错误吗?微软的缺陷有什么解决方法吗?

根据其他帖子,我已经尝试删除并重新安装一些 KB,但无济于事。

如果有办法用这个 FtpWebRequest 对象发出“chdir”,我可能会解决这个问题。但我什么都找不到。

这似乎不是访问权限问题。否则服务器应该返回 550。

有一些关于在数据端口上恢复会话的帖子,但是,由于这不会在一个文件夹级别上失败,只有在两个文件夹级别上,数据连接似乎不是问题。

有人有什么建议吗?

【问题讨论】:

  • 您可能没有权限在默认登录文件夹上执行 ListDirectory。错误 150 " 文件状态正常;即将打开数据连接。您可以将默认启动文件夹添加到 uri。请参阅:stackoverflow.com/questions/330155/…
  • 当我从使用 System.Net.FtpWebRequest 转而使用第三方 FTP 库时,解决了我最头疼的一些文件传输问题; FtpWebRequest 有点像对待 HTTP 服务器一样对待 FTP 服务器,而通常的 FTP 对话更像是一个持久会话。看看 WinSCP 的 .net 包装器 - 作者居住在这里,是技术建议的重要来源
  • 谢谢@CaiusJard。 – 如果 OP 想要坚持使用 FtpWebRequest,我们需要 log files 用于分叉和失败文件夹。..
  • 谢谢@MartinPrikryl C# 不是我选择的语言,这个 WebRequest 作为 FTP “WannaBe”太可怕了。我不知道日志记录选项。这可能会有所帮助。
  • 谢谢@jdweng。我得到了踪迹,并比较了好与坏。我怀疑这是权限问题。服务器位于一家有繁文缛节的庞然大物公司,希望我们能解开其中的一部分。

标签: c# ftp ftpwebrequest


【解决方案1】:

我发现了问题所在。这可能不是一个完整的解决方案,但它是一种解决方法。

首先,感谢 MartinPrikryl 引导我查看日志。一段日志如下所示:

System.Net Information: 0 : [24980] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=188, returned code=ContinueNeeded).
System.Net Information: 0 : [24980] FtpWebRequest#8810861::(Releasing FTP connection#49582139.)
System.Net Error: 0 : [24980] Exception in FtpWebRequest#8810861::GetResponse - The remote server returned an error: 150 Opening data connection. List started
..
   at System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
   at System.Net.CommandStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at System.Net.ConnectionPool.Destroy(PooledStream pooledStream)
   at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
   at System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage)
   at System.Net.FtpWebRequest.GetResponse()

因此,这似乎来自服务器提前关闭的数据连接。我不知道这个服务器是什么,或者它是什么风格的 *NIX。

我的解决方案是简单地改变

request.Method = WebRequestMethods.Ftp.ListDirectory;

request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

这将导致必须手动解析的 Unix 样式列表。在这种空目录的情况下,它只是:

dr-xr-xr-x   0 --NA--   --NA--            2 Dec 18 15:48 .
dr-xr-xr-x   0 --NA--   --NA--           16 Dec 18 15:48 ..

所以,有东西要读,数据通道不会过早关闭。

这不同于 Windows 风格的目录列表(显然不是空列表)

12-28-20  06:45PM       <DIR>          Some_Folder
10-07-20  09:35AM                 1148 a_file

因此,当使用“ListDirectoryDe​​tails”时,有必要确定哪种类型的服务器提供了回复,这是一项非常简单的任务。

注意:

我在本地 Ubuntu 机器上重复了测试,并没有遇到客户服务器给我的这个问题。所以我不清楚 vsftpd 和他们的服务器之间有什么区别,它不能识别自己(显然是出于安全原因)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-22
    • 2016-09-12
    • 1970-01-01
    • 2020-07-23
    • 2011-06-04
    • 2012-11-18
    相关资源
    最近更新 更多