Ben*_*bin 6 c# ftp ssl ftpwebrequest fluentftp
我正在尝试在代码中通过 SSL 打开 FTP 连接。我可以使用 WinSCP 的 FileZilla 连接并列出目录。但是当使用 .NET 代码列出目录时FtpWebClient,我收到错误
(425) 无法打开数据连接
由于我能够从同一台计算机使用 FileZilla 进行连接,因此我不确定如何解决此问题。
这是我的代码
public void FtpStuff()
{
string url = "ftp://my.server.com";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("myname", "password");
request.EnableSsl = true;
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
// This is the line that throws the exception
string line = streamReader.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
我也尝试过FluentFTP。这是我的代码。我得到了例外
无法建立数据连接:不允许操作。
public void FtpStuff()
{
FtpClient client = new FtpClient();
client.Host = "my.server.com";
client.Credentials = new NetworkCredential("myname", "password");
client.EncryptionMode = FtpEncryptionMode.Explicit;
client.Connect();
// This line gives me an exception.
var files = client.GetListing();
}
Run Code Online (Sandbox Code Playgroud)
这是 FluentFTP 的日志信息。我更改了真实的用户名和IP,但其余数据(包括端口)是真实数据。我的 FTP 服务提供商指定我必须在端口 21 上进行连接。问题似乎是在EPSV发出命令并在新端口上建立连接后发生的。
public void FtpStuff()
{
string url = "ftp://my.server.com";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("myname", "password");
request.EnableSsl = true;
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
// This is the line that throws the exception
string line = streamReader.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
这是我的 FileZilla 日志。
public void FtpStuff()
{
FtpClient client = new FtpClient();
client.Host = "my.server.com";
client.Credentials = new NetworkCredential("myname", "password");
client.EncryptionMode = FtpEncryptionMode.Explicit;
client.Connect();
// This line gives me an exception.
var files = client.GetListing();
}
Run Code Online (Sandbox Code Playgroud)
我还可以使用 WinSCP 进行连接。正如评论中所建议的,我确实检查了打开数据连接时是否重用了 TLS/SSL 会话 ID。看来确实如此。
# Connect()
The thread 0x5514 has exited with code 0 (0x0).
The thread 0xc80 has exited with code 0 (0x0).
The thread 0x89d4 has exited with code 0 (0x0).
Status: Connecting to 123.123.123.123:21
Response: 220 FTP Server Ready
Command: AUTH TLS
Response: 234 AUTH TLS successful
Status: FTPS Authentication Successful
Status: Time to activate encryption: 0h 0m 0s. Total Seconds: 0.1339995.
Command: USER me@mysite.com
The thread 0x6ddc has exited with code 0 (0x0).
Response: 331 Password required for me@mysite.com
Status: Testing connectivity using Socket.Poll()...
Command: PASS ***
Response: 230-***************************************************************************
Response: NOTICE TO USERS
Response: This computer system is private property. It is for authorized use only.
Response: Users (authorized or unauthorized) have no explicit or implicit
Response: expectation of privacy.
Response:
Response: Any or all uses of this system and all files on this system may be
Response: intercepted, monitored, recorded, copied, audited and inspected by
Response: using this system, the user consents to such interception, monitoring,
Response: recording, copying, auditing, inspection, and disclosure at the
Response: discretion of such personnel or officials. Unauthorized or improper use
Response: of this system may result in civil and criminal penalties and
Response: administrative or disciplinary action, as appropriate. By continuing to
Response: use this system you indicate your awareness of and consent to these terms
Response: and conditions of use. LOG OFF IMMEDIATELY if you do not agree to the
Response: conditions stated in this warning.
Response: ****************************************************************************
Response: 230 User me@mysite.com logged in
Command: PBSZ 0
Response: 200 PBSZ 0 successful
Command: PROT P
Response: 200 Protection set to Private
Command: FEAT
Response: 211-Features:
Response: AUTH TLS
Response: CCC
Response: CLNT
Response: EPRT
Response: EPSV
Response: HOST
Response: MDTM
Response: MFF modify;UNIX.group;UNIX.mode;
Response: MFMT
Response: MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.groupname*;UNIX.mode*;UNIX.owner*;UNIX.ownername*;
Response: PBSZ
Response: PROT
Response: REST STREAM
Response: SIZE
Response: SSCN
Response: TVFS
Response: 211 End
Status: Text encoding: System.Text.ASCIIEncoding
Command: SYST
Response: 215 UNIX Type: L8
# GetListing(null, Auto)
# GetWorkingDirectory()
Command: PWD
Response: 257 "/" is the current directory
Command: TYPE I
Response: 200 Type set to I
# OpenPassiveDataStream(AutoPassive, "MLSD /", 0)
Command: EPSV
Response: 229 Entering Extended Passive Mode (|||50304|)
Status: Connecting to 123.123.123.123:50304
Command: MLSD /
Response: 150 Opening BINARY mode data connection for MLSD
Status: FTPS Authentication Successful
Status: Time to activate encryption: 0h 0m 0s. Total Seconds: 0.1210002.
+---------------------------------------+
-----------------------------------------
Status: Disposing FtpSocketStream...
# CloseDataStream()
Response: 425 Unable to build data connection: Operation not permitted
Status: Disposing FtpSocketStream...
Exception thrown: 'FluentFTP.FtpCommandException' in FluentFTP.dll
Run Code Online (Sandbox Code Playgroud)
Mar*_*ryl 11
.NET框架不支持TLS/SSL会话重用。如果您的服务器需要它(它看起来是什么、现在很常见以及对安全性有什么好处),则您不能使用FtpWebRequestFluentFTP。两者都使用 TLS/SSL 的 .NET 实现。
您必须使用使用自己的 TLS/SSL 实现的 FTP 库。
\n您可以使用我的 WinSCP .NET 程序集。尽管与 FluentFTP 相反,它不是本机 .NET 库,但它依赖于外部二进制文件。但这就是让它发挥作用的原因。
\n一些参考:
\ndotnet上面的 GitHub 链接)。