如何在C#中发送任意FTP命令

我已经使用C#中的FtpWebRequest类实现了上传,下载,删除等function。 这是相当直接的。

我现在需要做的是支持发送任意FTP命令,如

 quote SITE LRECL=132 RECFM=FB or quote SYST 

以下是我们的app.config直接配置示例:

   quote SITE LRECL=132 RECFM=FB  

我还在研究如何使用FtpWebRequest来做到这一点。 我接下来可能会尝试WebClient类。 任何人都可以更快地指出我正确的方向吗? 谢谢!

更新:我得出了同样的结论,因为.NET Framework 3.5 FtpWebRequest不支持WebRequestMethods.Ftp.*任何内容。 我会尝试一些其他post推荐的第三方应用。 谢谢您的帮助!

我不认为可以用FtpWebRequest完成…指定FTP命令的唯一方法是通过Method属性,文档说明:

请注意, WebRequestMethods.Ftp类中定义的字符串是Method属性唯一受支持的选项。 将Method属性设置为任何其他值将导致ArgumentExceptionexception。

SITE和SYST不属于预定义的选项,所以我猜你被卡住了……

不要浪费时间去尝试WebClient类,它会比FtpWebRequest提供更少的灵活性。

但是,有很多第三方FTP实现,开源或商业,我很确定其中一些可以处理自定义命令……

正如Thomas Levesque在回答中所说, FtpWebRequest对你没有帮助。 您可以使用一些第三方解决方案或以下简化的基于TcpClient的代码,我已经使用Visual Basic编写的答案进行了重构:

 public static void SendFtpCommand() { var serverName = "[FTP_SERVER_NAME]"; var port = 21; var userName = "[FTP_USER_NAME]"; var password = "[FTP_PASSWORD]" var command = "SITE CHMOD 755 [FTP_FILE_PATH]"; var tcpClient = new TcpClient(); try { tcpClient.Connect(serverName, port); Flush(tcpClient); var response = TransmitCommand(tcpClient, "user " + userName); if (response.IndexOf("331", StringComparison.OrdinalIgnoreCase) < 0) throw new Exception(string.Format("Error \"{0}\" while sending user name \"{1}\".", response, userName)); response = TransmitCommand(tcpClient, "pass " + password); if (response.IndexOf("230", StringComparison.OrdinalIgnoreCase) < 0) throw new Exception(string.Format("Error \"{0}\" while sending password.", response)); response = TransmitCommand(tcpClient, command); if (response.IndexOf("200", StringComparison.OrdinalIgnoreCase) < 0) throw new Exception(string.Format("Error \"{0}\" while sending command \"{1}\".", response, command)); } finally { if (tcpClient.Connected) tcpClient.Close(); } } private static string TransmitCommand(TcpClient tcpClient, string cmd) { var networkStream = tcpClient.GetStream(); if (!networkStream.CanWrite || !networkStream.CanRead) return string.Empty; var sendBytes = Encoding.ASCII.GetBytes(cmd + "\r\n"); networkStream.Write(sendBytes, 0, sendBytes.Length); var streamReader = new StreamReader(networkStream); return streamReader.ReadLine(); } private static string Flush(TcpClient tcpClient) { try { var networkStream = tcpClient.GetStream(); if (!networkStream.CanWrite || !networkStream.CanRead) return string.Empty; var receiveBytes = new byte[tcpClient.ReceiveBufferSize]; networkStream.ReadTimeout = 10000; networkStream.Read(receiveBytes, 0, tcpClient.ReceiveBufferSize); return Encoding.ASCII.GetString(receiveBytes); } catch { // Ignore all irrelevant exceptions } return string.Empty; } 

通过FTP时,您可以期待以下流程:

 220 (vsFTPd 2.2.2) user [FTP_USER_NAME] 331 Please specify the password. pass [FTP_PASSWORD] 230 Login successful. SITE CHMOD 755 [FTP_FILE_PATH] 200 SITE CHMOD command ok. 

您可以尝试我们的Rebex FTP组件 :

 // create client and connect Ftp client = new Ftp(); client.Connect("ftp.example.org"); client.Login("username", "password"); // send SITE command // note that QUOTE and SITE are ommited. QUOTE is command line ftp syntax only. client.Site("LRECL=132 RECFM=FB"); // send SYST command client.SendCommand("SYST"); FtpResponse response = client.ReadResponse(); if (response.Group != 2) ; // handle error // disconnect client.Disconnect(); 

使用sendCommand("SITE LRECL=242 BLKSIZE=0 RECFM=FB");