2012-10-26 7 views
7

Il mio problema è che sto creando un client FTP, e finora funziona perfettamente oltre a un dettaglio minore, che continua a infastidirmi. Ho bisogno di sapere quante linee il messaggio di benvenuto dell'FTP si estende oltre ... E questo non può essere accettabile!Come sapere la fine del messaggio di benvenuto FTP

private Socket connection; 
    private PrintWriter outStream; 
    private Scanner inStream; 

public void InitiateConnection() throws IOException 
{ 
    log.Info(this, "Initiating connection to host: " + host + ":" + port); 
    connection = new Socket(host, port); 
    log.Info(this, "Connection initiated."); 
    outStream = new PrintWriter(connection.getOutputStream(), true); 
    inStream = new Scanner(connection.getInputStream()); 
    Listen(); 
    Listen();  
    Listen(); 
} 

public String Listen() throws IOException 
{ 
    if(connection == null) 
     throw new IOException("Connection not initiated yet"); 
    String response = inStream.nextLine(); 
    log.Info(this, "Response: " + response); 
    return response; 
} 

Questa è la semplice messa a punto, ho lasciato fuori tutti gli altri codici, in quanto non ha nulla a che fare con il mio problema.

Ho provato più cose per cercare di raggiungere questo obiettivo. Impossibile Soluzione 1:

String response = ""; 
while(response != null) 
    Listen(); 

non riuscita Soluzione 2:

while(connection.getInputStream().available > 0) 
    Listen(); 

e innumerevoli altri ... Ma, o non funziona, oppure i metodi di blocco e attendere nuovi input. Ho anche provato con un timeout, ma non funziona perfettamente, non è una soluzione adeguata a questo problema ...

Ho bisogno di essere in grado di ottenere l'intero messaggio di benvenuto dal server FTP, senza sapere la quantità di linee ... perciò in grado di ottenere sia questo:

Response: 220-FileZilla Server version 0.9.39 beta 
Response: 220-written by Tim Kosse ([email protected]) 
Response: 220 Please visit http://sourceforge.net/projects/filezilla/ 

E questo:

Response: 220-FileZilla Server version 0.9.40 beta 
Response: 220 Welcome to Andrés FTP Server 

risposta

7

Se si dispone di uno sguardo da vicino i messaggi, si vede che tutti, ma le ultime righe hanno un - dietro il codice di stato. L'ultima riga ha un , tuttavia, indicando, beh, l'ultima riga.

Si può leggere che nel RFC 959, paragrafo 4.2:

Così il formato per il multi-linea di risposte è che la prima linea inizierà con l'esatto codice di risposta desiderata, seguita immediatamente da un trattino, "-" (noto anche come Minus), seguito dal testo . L'ultima riga inizierà con lo stesso codice, seguita immediatamente da da Spazio, opzionalmente un testo e il codice di fine riga Telnet .

Non viene detto nulla sulla seconda o la penultima riga, ma è logico che abbiano lo stesso formato del primo.


Aggiornamento: Il protocollo FTP sembra essere mal documentati, ma ho trovato un altro riferimento che indica lo stesso come me sopra:

Il TCP/IP Guide menzioni che

E 'possibile per una risposta per contenere più di una riga di testo. In questo caso, ogni riga inizia con il codice di risposta e tutte le righe tranne l'ultima hanno un trattino tra il codice di risposta e il testo di risposta, per indicare che la risposta continua. L'ultima riga ha uno spazio tra il codice di risposta e il testo di risposta, proprio come una risposta a linea singola. Questa funzione viene spesso utilizzata per fornire ulteriori informazioni di risposta dopo che un utente effettua l'accesso tramite il codice di risposta 230.

+0

Questo è il formato di risposta * multilinea *. Dalla stessa sezione: "Una risposta FTP consiste in un numero di tre cifre (trasmesso come tre caratteri alfanumerici) seguito da un testo." Non è chiaro dalle specifiche ma se si avvia FileZilla vedrete che l'unica risposta ML nella procedura di connessione è la risposta 211 sul comando FEAT. – linski

+0

si aggiornerà di conseguenza comunque :) – linski

0

hai provato in questo modo?

StringBuilder response = new StringBuilder(); 
    BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); 
    do {    
     response.append(br.readLine());          
    } 
    while (br.ready()); 

Mentre il metodo 's il BufferedReaderready():

dice se questo flusso è pronto per essere letto. Un flusso di caratteri bufferizzato è pronto se il buffer non è vuoto o se il flusso di caratteri sottostante è pronto.
Restituzioni:
Vero se la lettura successiva() è garantita per non bloccare per immissione, falso altrimenti. Nota che restituire false non garantisce che la prossima lettura bloccherà.

E 'in realtà un method .

UPDATE:

Come glglgl sottolineato ci sono due tipi di risposte in FTP:

  • "linea singola" risposta (il mio mandato)
  • risposta multilinea (termine spec)

Come ho detto nel commento, accendi FIlleZilla, connettiti e osserva il log (preferibilmente confrontando i comandi in uscita con la definizione delle specifiche) e vedrai perché la "linea singola" è citato

Su alcune implementazioni di server FTP il codice sopra riportato potrebbe funzionare, ma sicuramente non funzionerà su tutte le implementazioni, poiché non implementa correttamente la parte client del protocollo.Questa è la versione aggiornata:

String response; 
List<String> responseList = new ArrayList<String>(); 
boolean isMultilineStart = false, isMultilineEnd = false; 
String mlCode = null; 
do {    
    responseList.add(br.readLine());       
    if (!isMultilineStart) { 
     isMultilineStart = responseList.get(responseList.size()-1).matches("\\d\\d\\d-.*");     
     mlCode = responseList.get(responseList.size()-1).substring(0,3); 
    } 
    else { 
     isMultilineEnd = responseList.get(responseList.size()-1).startsWith(mlCode+" "); 
    } 
} 
while (br.ready() || (isMultilineStart && !isMultilineEnd)); 
response = Arrays.deepToString(responseList.toArray()); 
+0

No, non l'ho fatto, ma ci proverò sicuramente. –

+1

Ma non si sa se il server ha davvero finito, o se un pacchetto è in corso, ma non è ancora arrivato. Meglio affidarsi alle strutture fornite dal protocollo. – glglgl

+0

@glglgl "Il mio problema è che sto creando un client FTP ..." sembra che stia implementando il lato client del protocollo. – linski

Problemi correlati