2010-02-23 15 views
8

Implementé la capacidad de cargar, descargar, eliminar, etc. utilizando la clase FtpWebRequest en C#. Eso es bastante sencillo.Cómo enviar comandos FTP arbitrarios en C#

Lo que hay que hacer ahora es el soporte envío de comandos FTP arbitrarios como

quote SITE LRECL=132 RECFM=FB 
or 
quote SYST 

Aquí está un ejemplo de configuración directamente desde nuestra app.config:

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

Todavía estoy investigando cómo hacer esto usando FtpWebRequest. Probablemente probaré la clase WebClient a continuación. ¿Alguien puede apuntarme en la dirección correcta más rápido? ¡Gracias!

ACTUALIZACIÓN: He llegado a la misma conclusión, ya que .NET Framework 3.5 FtpWebRequest no admite nada, excepto lo que está en WebRequestMethods.Ftp.*. Probaré una aplicación de terceros recomendada por algunas de las otras publicaciones. ¡Gracias por la ayuda!

+0

¿Te ha prueba Rebex FTP con esos comandos? funcionó bien? – Askolein

Respuesta

9

No creo que se puede hacer con FtpWebRequest ... La única manera de especificar un comando FTP es a través de la propiedad Method, y los estados de documentación:

Tenga en cuenta que las cadenas de la WebRequestMethods.Ftp class son las únicas opciones admitidas para la propiedad Method. Establecer la propiedad Method a cualquier otro valor dará como resultado una excepción ArgumentException.

SITIO y SIST no se encuentran entre las opciones predefinidas, así que supongo que le pegan ...

No pierda el tiempo para tratar la clase WebClient, que le dará aún menos flexibilidad que FtpWebRequest .

Sin embargo, hay un montón de terceros aplicación FTP, de código abierto o comercial, y estoy bastante seguro de que algunos de ellos pueden manejar comandos personalizados ...

3

Usted puede probar nuestro 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(); 
-5

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

+3

Esto es muy inútil porque no se proporciona información. ¿Qué es "sendCommand" es una biblioteca de terceros, ¿tiene algo que ver con FtpWebRequest ??? –

6

El FtpWebRequest no le ayudará como Thomas Levesque ha dicho en su answer. Puede utilizar algunas soluciones de terceros o la siguiente, simplificados TcpClient código basado en lo que he rediseñado desde una 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; 
} 

se puede esperar que el siguiente flujo mientras que consigue a través del 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. 
Cuestiones relacionadas