c# – 从(特定)服务器下载FTP文件适用于.NET 4,但不适用于.NET 2
更新(此问题的原因):
好吧,我在@MitchelSellers的评论的帮助下进行了管理 – 找出问题的确切位置,并且我正在努力寻找解决方案. >显然这个服务器不允许命令CWD(更改工作目录). 所以,我正试图找到一种方法使它在.NET 2.0上运行. 原来的问题: 这是我的代码: Private Sub DownloadTestFile() Dim filePath As String = "ftp://ftp.kohlandfrisch.com/testfile" Dim request As FtpWebRequest Dim buffer(1023) As Byte Dim bytesIn As Integer request = DirectCast(WebRequest.Create(filePath),FtpWebRequest) request.Method = WebRequestMethods.Ftp.DownloadFile request.Credentials = New NetworkCredential("username","password") request.UseBinary = False request.UsePassive = True request.Proxy = Nothing Using stream As IO.Stream = request.GetResponse.GetResponseStream Using output = IO.File.Create(localFilePath) bytesIn = 1 Do Until bytesIn < 1 bytesIn = stream.Read(buffer,1024) If bytesIn > 0 Then output.Write(buffer,bytesIn) Loop End Using End Using End Sub 在.NET 4或4.x上运行该代码时,它可以正常工作.但是,当在.NET 2.0上运行它(我必须使用.NET 2.0)时,它会在调用request.GetResponse时抛出异常.这是异常消息:
我发现从.NET 2.0发出的请求肯定有问题,所以我决定使用Wireshark捕获请求和响应,我的假设是正确的,但我仍然不明白问题究竟是什么,因为我’ m在两个.NET版本上使用相同的代码. Wireshark结果 .NET 4.5.2 .NET 2.0 有任何想法吗? 旁注:尽管我的代码是在VB中,但欢迎使用C#代码的任何答案. 解决方法
根据评论更新:
.NET 2不尊重该标志:-( if (m_PreviousServerPath != newServerPath) { if (!m_IsRootPath && m_LoginState == FtpLoginState.LoggedIn && m_LoginDirectory != null) { newServerPath = m_LoginDirectory+newServerPath; } m_NewServerPath = newServerPath; commandList.Add(new PipelineEntry(FormatFtpCommand("CWD",newServerPath),PipelineEntryFlags.UserCommand)); } 所以基本上CWD在.NET 2中是硬编码的. 一种非常不寻常的方式可能是从.NET应用程序调用/自动化DOS命令ftp … 留待参考: MS在此记录了.NET 2和.NET 4之间的这种行为变化:https://support.microsoft.com/en-au/help/2134299/system.net.ftpwebrequest-class-behaves-differently-in-.net-framework-4-vs-.net-framework-3.5 我怀疑在.NET 2.0中删除描述的标志值得尝试 – 类似于: private static void SetMethodRequiresCWD() { Type requestType = typeof(FtpWebRequest); FieldInfo methodInfoField = requestType.GetField("m_MethodInfo",BindingFlags.NonPublic | BindingFlags.Instance); Type methodInfoType = methodInfoField.FieldType; FieldInfo knownMethodsField = methodInfoType.GetField("KnownMethodInfo",BindingFlags.Static | BindingFlags.NonPublic); Array knownMethodsArray = (Array)knownMethodsField.GetValue(null); FieldInfo flagsField = methodInfoType.GetField("Flags",BindingFlags.NonPublic | BindingFlags.Instance); int MustChangeWorkingDirectoryToPath = 0x100; foreach (object knownMethod in knownMethodsArray) { int flags = (int)flagsField.GetValue(knownMethod); flags &= (~MustChangeWorkingDirectoryToPath); flagsField.SetValue(knownMethod,flags); } } 对不起 – 我现在不能尝试这个,所以这更像是一个建议…… 编辑:或者你可以使用一些ftp库,它的行为类似于.NET 4. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |