如何在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
属性设置为任何其他值将导致ArgumentException
exception。
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");