【问题标题】:How to send arbitrary FTP commands in C#如何在 C# 中发送任意 FTP 命令
【发布时间】:2023-03-20 09:45:01
【问题描述】:

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

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

quote SITE LRECL=132 RECFM=FB
or 
quote SYST

这是直接来自我们app.config 的示例配置:

<!-- The following commands will be executed before any uploads occur -->
<extraCommands>
     <command>quote SITE LRECL=132 RECFM=FB</command>
</extraCommands>

我仍在研究如何使用FtpWebRequest 执行此操作。接下来我可能会尝试WebClient 课程。任何人都可以更快地指出我正确的方向吗?谢谢!

更新: 我得出了同样的结论,从 .NET Framework 3.5 开始,FtpWebRequest 不支持任何东西,除了WebRequestMethods.Ftp.* 中的内容。我将尝试其他一些帖子推荐的第三方应用程序。谢谢您的帮助!

【问题讨论】:

  • 你用这些命令试过 Rebex FTP 吗?效果好吗?

标签: c# ftp ftpwebrequest


【解决方案1】:

我认为 FtpWebRequest 无法做到这一点... 指定 FTP 命令的唯一方法是通过 Method 属性,文档指出:

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

SITE 和 SYST 不在预定义选项中,所以我猜你被卡住了...

不要浪费时间尝试 WebClient 类,它给你的灵活性甚至比 FtpWebRequest 还要低。

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

【讨论】:

    【解决方案2】:

    你可以试试我们的Rebex FTP component:

    // 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();
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 这是非常无用的,因为没有提供任何信息。什么是“sendCommand”是第三方库,和FtpWebRequest有关系吗???
      【解决方案4】:

      FtpWebRequest 不会像Thomas Levesque 在他的answer 中所说的那样帮助您。您可以使用一些第三方解决方案或以下基于TcpClient 的简化代码,我已从answer written in 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.
      

      【讨论】:

        猜你喜欢
        • 2015-09-24
        • 1970-01-01
        • 1970-01-01
        • 2012-05-12
        • 2018-01-30
        • 2015-12-21
        • 2016-01-30
        • 2014-07-31
        • 1970-01-01
        相关资源
        最近更新 更多