访问 FTP 服务器时出现未知命令 FEAT
Unknown command FEAT when accessing FTP server
我刚刚根据此处提供的代码 http://www.codeguru.com/csharp/csharp/cs_network/sockets/article.php/c7409/A-C-FTP-Server.htm 创建了一个 FTP 服务器。然后我为 FtpClient 安装了 Nuget 包,这样我就可以创建一个连接到 FTP 服务器的测试 FTP 客户端。以下是我的代码:
[TestMethod]
async public Task TestMethod1() // wanted to make it async as I may connect have something related to database in future
{
var client = new FtpClient
{
Host = "127.0.0.1",
Port = 21,
Credentials = new NetworkCredential
{
UserName = "123",
Password = "123",
},
DataConnectionType = FtpDataConnectionType.PASV // If I don't add this, I get EPSV unknown command
};
await client.ConnectAsync();
Debug.WriteLine("Connected");
client.SetWorkingDirectory(@"C:\Users\myname\Desktop");
Debug.WriteLine(client.GetWorkingDirectory());
try
{
var items = client.GetListing(); // Exception shows up here.
Debug.WriteLine(items.Count());
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
问题可能是我的服务器中没有用于 FEAT 的命令处理程序。但是,我的 FTP 服务器在 filezilla 上运行得很好。如果需要命令处理程序,有人可以为此提供代码吗?
如果我忽略这个错误,我会在测试方法中得到这个异常 "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."
有什么想法吗?
[编辑]
这是完整的例外:
Test method Blackhawk.Core.FtpServer.Test.UnitTest1.TestMethod1 threw exception:
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at System.Net.FtpClient.FtpSocketStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.FtpClient.FtpSocketStream.ReadLine(Encoding encoding)
at System.Net.FtpClient.FtpClient.GetReply()
at System.Net.FtpClient.FtpClient.Execute(String command)
at System.Net.FtpClient.FtpClient.OpenPassiveDataStream(FtpDataConnectionType type, String command, Int64 restart)
at System.Net.FtpClient.FtpClient.OpenDataStream(String command, Int64 restart)
at System.Net.FtpClient.FtpClient.GetListing(String path, FtpListOption options)
at System.Net.FtpClient.FtpClient.GetListing(String path)
at Blackhawk.Core.FtpServer.Test.UnitTest1.<TestMethod1>d__2.MoveNext() in UnitTest1.cs: line 44
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
我可以通过将数据连接类型更改为 AutoActive 来解决问题。这是有效的最终代码:
[TestMethod]
async public Task FtpTestUser1()
{
var client = new FtpClient
{
Host = "127.0.0.1",
Port = 21,
Encoding = System.Text.Encoding.Default,
Credentials = new NetworkCredential
{
// Storing username, password and default directory in a .dat file
UserName = "123",
Password = "123",
},
DataConnectionType = FtpDataConnectionType.AutoActive // Changed this part.
};
await client.ConnectAsync();
Debug.WriteLine("Connected");
var path = @"Test"; // This path is now relative to the default directory
client.SetWorkingDirectory(path);
Debug.WriteLine(client.GetWorkingDirectory());
var items = client.GetListing();
Assert.IsTrue(items.Any());
Debug.WriteLine(items.Count());
foreach (var ftpListItem in items)
{
Debug.WriteLine(string.Format("File name is {0}", ftpListItem.Name));
}
}
我刚刚根据此处提供的代码 http://www.codeguru.com/csharp/csharp/cs_network/sockets/article.php/c7409/A-C-FTP-Server.htm 创建了一个 FTP 服务器。然后我为 FtpClient 安装了 Nuget 包,这样我就可以创建一个连接到 FTP 服务器的测试 FTP 客户端。以下是我的代码:
[TestMethod]
async public Task TestMethod1() // wanted to make it async as I may connect have something related to database in future
{
var client = new FtpClient
{
Host = "127.0.0.1",
Port = 21,
Credentials = new NetworkCredential
{
UserName = "123",
Password = "123",
},
DataConnectionType = FtpDataConnectionType.PASV // If I don't add this, I get EPSV unknown command
};
await client.ConnectAsync();
Debug.WriteLine("Connected");
client.SetWorkingDirectory(@"C:\Users\myname\Desktop");
Debug.WriteLine(client.GetWorkingDirectory());
try
{
var items = client.GetListing(); // Exception shows up here.
Debug.WriteLine(items.Count());
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
问题可能是我的服务器中没有用于 FEAT 的命令处理程序。但是,我的 FTP 服务器在 filezilla 上运行得很好。如果需要命令处理程序,有人可以为此提供代码吗?
如果我忽略这个错误,我会在测试方法中得到这个异常 "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."
有什么想法吗?
[编辑] 这是完整的例外:
Test method Blackhawk.Core.FtpServer.Test.UnitTest1.TestMethod1 threw exception:
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at System.Net.FtpClient.FtpSocketStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.FtpClient.FtpSocketStream.ReadLine(Encoding encoding)
at System.Net.FtpClient.FtpClient.GetReply()
at System.Net.FtpClient.FtpClient.Execute(String command)
at System.Net.FtpClient.FtpClient.OpenPassiveDataStream(FtpDataConnectionType type, String command, Int64 restart)
at System.Net.FtpClient.FtpClient.OpenDataStream(String command, Int64 restart)
at System.Net.FtpClient.FtpClient.GetListing(String path, FtpListOption options)
at System.Net.FtpClient.FtpClient.GetListing(String path)
at Blackhawk.Core.FtpServer.Test.UnitTest1.<TestMethod1>d__2.MoveNext() in UnitTest1.cs: line 44
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
我可以通过将数据连接类型更改为 AutoActive 来解决问题。这是有效的最终代码:
[TestMethod]
async public Task FtpTestUser1()
{
var client = new FtpClient
{
Host = "127.0.0.1",
Port = 21,
Encoding = System.Text.Encoding.Default,
Credentials = new NetworkCredential
{
// Storing username, password and default directory in a .dat file
UserName = "123",
Password = "123",
},
DataConnectionType = FtpDataConnectionType.AutoActive // Changed this part.
};
await client.ConnectAsync();
Debug.WriteLine("Connected");
var path = @"Test"; // This path is now relative to the default directory
client.SetWorkingDirectory(path);
Debug.WriteLine(client.GetWorkingDirectory());
var items = client.GetListing();
Assert.IsTrue(items.Any());
Debug.WriteLine(items.Count());
foreach (var ftpListItem in items)
{
Debug.WriteLine(string.Format("File name is {0}", ftpListItem.Name));
}
}