Faire discuter un serveur FTP fait maison en Java et un client FTP fait avec Apache Commons Net
Bonjour à tous :)
Voila, pour la fac j'ai dû faire un serveur FTP en Java. J'y suis parvenu, il fonctionne plutôt pas mal avec Filezilla comme client par exemple. :D
Maintenant on doit faire une passerelle REST sous glassfish pour utiliser ce serveur FTP.
Pour que la passerelle REST puisse parler avec mon serveur il faut donc que je code un bout de client FTP et pour cela j'utilise la librairie Apache Commons Net (https://commons.apache.org/proper/commons-net//).
Mais voila, quand je dis à mon client FTP "connect" (ligne 37 du deuxième bout de code que je fournis), il envoie bien la requête, mon serveur FTP crée bien son thread pour ce client et lui renvoie bien "220 Service ready" mais tout s'arrête là.
Mon client ne bouge plus (alors qu'il le devrait. Il devrait passer à la ligne "reply = ftp.getReplyCode();") et mon serveur après avoir répondu ça attends une commande de la part du client (comportement normal d'un serveur FTP).
Je pense qu'ils, même si la Socket est correctement créée, n'arrivent pas à se parler. Peut être un problème d'encoding ?
Voici quelques bout de code qui pourront vous être utile pour essayer de m'aider :
Tout d'abord un bout de mon serveur FTP. C'est un bout de la classe qui gère le canal de commandes.
Pour chaque client qui se connecte un thread de cette classe est lancé.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
// runner du thread qui est lancé pour chaque client.
// Il se charge de créer les reader et writer pour lire et écrire dans la Socket puis appel la méthode "processRequest" qui va traiter les requêtes du client (boucle infini).
@Override
public void run() {
try {
readerCmd = new BufferedReader(new InputStreamReader(
socketCmd.getInputStream()));
writerCmd = new PrintWriter(new OutputStreamWriter(
socketCmd.getOutputStream()), true);
processRequest();
} catch (final Exception e) {
e.printStackTrace();
} finally {
try {
socketCmd.close();
} catch (final IOException e) {
e.printStackTrace();
}
}
}
// Le début de ma méthode processRequest. Elle répond au client qu'elle est prête ("220 Service Ready")
//puis avec son readerCmd.readLine() attend les commandes du client.
/**
* Main controler
*
* @throws Exception
*/
private void processRequest() throws Exception {
reply(220, "Service ready");
String line;
while ((line = readerCmd.readLine()) != null) {
// ....
}
// Ma méthode qui est chargé d'envoyé les réponses au client sur le canal de commandes.
int reply(final int code, final String text) {
writerCmd.println(code + " " + text);
return code;
} |
Et voici le code de mon client ftp :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
public class DAOOverFTP {
private final FTPClient ftp;
private final String currentDir;
private final String username = "test";
private final String password = "test";
public DAOOverFTP() throws IOException {
final FTPClientConfig config = new FTPClientConfig();
config.setDefaultDateFormatStr("MMM dd HH:mm");
ftp = new FTPClient();
ftp.configure(config);
ftp.addProtocolCommandListener(new PrintCommandListener(
new PrintWriter(System.out), true));
// ftp.setAutodetectUTF8(true);
// ftp.setBufferSize(1024);
// ftp.setReceiveBufferSize(1024);
// ftp.setSendBufferSize(1024);
// ftp.setConnectTimeout(120 * 120);
ftp.setControlEncoding("UTF-8");
// no keep alive control
ftp.setControlKeepAliveReplyTimeout(0);
ftp.setControlKeepAliveTimeout(0);
// ftp.setCopyStreamListener(createListener());
// ftp.setFileStructure(FTP.FILE_STRUCTURE);
// ftp.setServerSocketFactory(ne)
// ftp.setSocketFactory(factory)
int reply;
try {
ftp.connect(InetAddress.getLocalHost().getHostName(), 5555);
reply = ftp.getReplyCode();
System.out.println("Connected to "
+ InetAddress.getLocalHost().getHostName() + " on " + 5555);
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
System.err.println("FTP server refused connection.");
System.exit(1);
}
} catch (final IOException e) {
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (final IOException f) {
// do nothing
}
}
System.err.println("Could not connect to server.");
e.printStackTrace();
System.exit(1);
}
if (!ftp.login(username, password)) {
ftp.logout();
}
System.out.println("Remote system is " + ftp.getSystemType());
ftp.setFileType(FTP.BINARY_FILE_TYPE);
// ftp.user();
// ftp.pass("jules");
ftp.pasv();
currentDir = ftp.printWorkingDirectory();
System.out.println("currentDir : " + currentDir);
}
public List<String> getlistNames() throws IOException {
return Arrays.asList(ftp.listNames());
}
public List<String> getlistNames(final String pathname) throws IOException {
return Arrays.asList(ftp.listNames(pathname));
}
private static CopyStreamListener createListener() {
return new CopyStreamListener() {
private long megsTotal = 0;
@Override
public void bytesTransferred(final CopyStreamEvent event) {
bytesTransferred(event.getTotalBytesTransferred(),
event.getBytesTransferred(), event.getStreamSize());
}
@Override
public void bytesTransferred(final long totalBytesTransferred,
final int bytesTransferred, final long streamSize) {
final long megs = totalBytesTransferred / 1000000;
for (long l = megsTotal; l < megs; l++) {
System.err.print("#");
}
megsTotal = megs;
}
};
}
} |
Pour tester mon client FTP, j'utilise une petite classe JUnit que voici :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
@RunWith(JUnit4.class)
public class DAOOverFTPTest {
private DAOOverFTP daoOverFTP;
@Before
public void setUp() throws SocketException, IOException {
daoOverFTP = new DAOOverFTP();
}
@Test
public void test() throws IOException {
Assert.assertTrue(!daoOverFTP.getlistNames().isEmpty());
}
} |
Qu'en pensez vous ? Avez-vous une idée ?
Merci d'avane pour votre aide. :ccool:
Jules.