2009-11-13 11 views
1

J'essaie de récupérer une liste de fichiers à partir d'un serveur FTP, mais je reçois des réponses non-ASCII étranges.Récupérer une liste de fichiers d'un serveur FTP en C#

Voici le code que j'utilise:

public string[] getFileList(string mask) 
{ 
    if(!logined) 
    { 
    login(); 
    } 
    Socket cSocket = createDataSocket(); 
    this.getSslDataStream(cSocket); 
    sendCommand("PASV"); 
    sendCommand("LIST " + "*"+mask); 
    stream2.AuthenticateAsClient(remoteHost, 
     null, 
     System.Security.Authentication.SslProtocols.Ssl3 | 
     System.Security.Authentication.SslProtocols.Tls, 
     true); 
    if(!(retValue == 150 || retValue == 125)) 
    { 
    throw new IOException(reply.Substring(4)); 
    } 
    StringBuilder mes = new StringBuilder();  
    while(true) 
    { 
    int bytes = cSocket.Receive(buffer, buffer.Length, 0); 
    mes.Append(ASCII.GetString(buffer, 0, bytes)); 
    if(bytes < buffer.Length) 
    { 
     break; 
    } 
    } 
    string[] seperator = {"\r\n"}; 
    string[] mess = mes.ToString().Split(seperator, StringSplitOptions.RemoveEmptyEntries); 
    cSocket.Close(); 
    readReply(); 
    if(retValue != 226) 
    { 
    throw new IOException(reply.Substring(4)); 
    } 
    return mess; 
} 

La réponse que je reçois du serveur FTP est la suivante:

WRITE:PASV 

READ:227 Entering Passive Mode (10,0,2,24,5,119)` 

WRITE:LIST *.dat 

READ:150 Opening ASCII mode data connection for /bin/ls. 

READ:226 Transfer complete. 

Il arrête là. Le tableau de chaînes qu'il retourne contient un index avec des caractères non-ascii. On dirait un tas d'ordures. Peut-être ma partie ASCII.GetString est faux? Je ne suis pas tout à fait sûr.

Merci d'avance.

+0

Quelle version de .NET Framework utilisez-vous? – Kev

+0

Je suis désolé. 3.5. – Aaron

+0

Juste un commentaire ... Je peux télécharger et télécharger des fichiers correctement. L'inscription et le renvoi de la liste semblent être la seule chose que je ne peux pas faire. J'ai essayé LS, LIST, et NLST. LS n'est pas reconnu pour une raison quelconque, et LIST et NLST font la même chose. – Aaron

Répondre

4

Pour ce que ça vaut, l'espace de noms System.Net a les classes FtpWebRequest et FtpWebResponse commençant par .Net 2.0.

est ici un code que je l'ai utilisé qui écrit les fichiers de serveur dans un fichier local:

... 
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(address); 
ftpRequest.Credentials = new NetworkCredential(username, password); 
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 
ftpRequest.KeepAlive = false; 

FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); 

sr = new StreamReader(ftpResponse.GetResponseStream()); 
sw = new StreamWriter(new FileStream(fileName, FileMode.Create)); 

sw.WriteLine(sr.ReadToEnd()); 
sw.Close(); 

ftpResponse.Close(); 
sr.Close(); 
... 
+0

Je sais. J'utilise un code qui a été écrit il y a 2 ans, mais fonctionne très bien pour le téléchargement et le téléchargement dans d'autres programmes. Je voudrais utiliser le même code si possible. – Aaron

+0

Je ne voudrais pas tout réécrire - juste la liste des fichiers. –

+0

Ok. Je l'ai essayé, mais mon URI donne une exception de format inconnu. Ca devrait juste être mon nom de serveur ftp? – Aaron

6

J'ai écrit un assez facile à utiliser la bibliothèque de wrapper pour tous les trucs FtpWebRequest. Si vous voulez vérifier, c'est ici https://gist.github.com/1242616

Je l'utilise dans beaucoup d'environnements de production et il ne m'a pas encore échoué.

0
public Socket BuildDataConn(Socket FirstSocket) 
{ 
    string ret = ""; 
    string RemoteIP = ""; 
    int RemotePort = 0; 
    SendCommand("PASV"); 

    int id = 0; 
    id = strMsg.LastIndexOf(')'); 
    if (id != 0) 
    { 
     string tmp = strMsg.Substring(strMsg.LastIndexOf('(') + 1, id - strMsg.LastIndexOf('(') - 1); 
     string[] bByte = tmp.Split(','); 
     RemotePort = int.Parse(bByte[4]) * 256 + Byte.Parse(bByte[5]); 
     RemoteIP = bByte[0]+"." + bByte[1] + "." + bByte[2] + "." + bByte[3]; 
    } 
    Socket NewConn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    IPEndPoint RemoteIPPort = new IPEndPoint(IPAddress.Parse(RemoteIP), RemotePort); 
    try 
    { 
     NewConn.Connect(RemoteIPPort); 
    } 
    catch 
    { 
     throw new IOException("unable to Connect !"); 
    } 
    return NewConn; 
} 

Au lieu d'utiliser cSocket pour recevoir des données de réponse, vous devez obtenir une deuxième prise, puis utiliser la prise pour recevoir des données de réponse. le second socket répondra pour renvoyer des informations. Et assurez-vous que vous avez modifié votre répertoire de travail FTP avant d'envoyer la commande LIST.

public List<string> GetFileNames() 
{ 
    if (!bConnected) 
    { 
     Open(); 
    } 
    List<string> retObj = new List<string>(); 
    Socket dataSock = BuildDataConn(mySocket); 

    SendCommand("NLST"); 
    string dataSockMsg = ""; 
    buffer = new byte[BLOCK_SIZE]; 

    while (true) 
    { 
     int iBytes = dataSock.Receive(buffer, buffer.Length, 0); 
     dataSockMsg += System.Text.Encoding.ASCII.GetString(buffer, 0, iBytes); 
     if (iBytes < buffer.Length) 
     { 
      break; 
     } 
    } 

    string[] message = dataSockMsg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);  

    dataSock.Close(); 

    foreach (string obj in message) 
    { 
     retObj.Add(obj); 
    } 

    return retObj; 
} 
Questions connexes