
FAQ JavaConsultez toutes les FAQ
Nombre d'auteurs : 53, nombre de questions : 231, dernière mise à jour : 7 juin 2009
Sommaire→Fichiers, flux et réseaux→Réseaux- Comment établir une connexion FTP ?
- Comment puis-je faire un 'ping' en Java ?
- Comment connaître l'adresse IP de sa machine ?
- Comment spécifier un proxy pour se connecter à un serveur ?
- Comment envoyer une requête de type POST en utilisant une URL ?
- Comment établir une communication entre une applet et une servlet ?
- Pourquoi mes sockets sont plus longues à se connecter depuis java 5.0 ?
Rien n'est spécifiquement prévu dans l'Api pour gérer les connexions FTP. Mais à partir des RFC959 et 1123 et avec un peu de courage, vous pouvez faire votre propre client FTP.
Heureusement, d'autres programmeurs sont passés avant vous, et des bibliothèques sont à votre disposition :
- Java FTP Client Library disponible sous licence LGPL, avec toutes les fonctions nécessaires.
- FTPConnection également libre et complète (voir ci dessous).
- Jakarta Commons Net, disponible sous licence Apache, propose les implémentations clients de plusieurs protocoles de base d'Internet (dont le FTP).
Téléchargement : FTPConnection
Si vous avez Windows et une seule carte réseau, l'information n'est pas trop difficile à obtenir, ce petit code suffit :
String ip = InetAddress.getLocalHost ().getHostAddress ();
Sinon, cela va se compliquer. Il faut parcourir les interfaces réseaux et filter les bonnes addresses :
/**
* Retourne toutes les adresses ips des carte réseau de la machine. Retourne seulement les addresses IPV4
*
* @return Une liste des addresses ip
*/
public List<String> getIps(){
List<String> ips = new ArrayList<String>();
try{
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) { // carte reseau trouvee
NetworkInterface interfaceN = (NetworkInterface)interfaces.nextElement();
Enumeration<InetAddress> ienum = interfaceN.getInetAddresses();
while (ienum.hasMoreElements()) { // retourne l adresse IPv4 et IPv6
InetAddress ia = ienum.nextElement();
String adress = ia.getHostAddress().toString();
if( adress.length() < 16){ //On s'assure ainsi que l'adresse IP est bien IPv4
if(adress.startsWith("127")){ //Ce n'est pas l'adresse IP Local'
System.out.println(ia.getHostAddress());
}
else if(adress.indexOf(":") > 0){
System.out.println(ia.getHostAddress()); // les ":" indique que c'est une IPv6"
}
}
ips.add(adress);
}
}
}
catch(Exception e){
System.out.println("pas de carte reseau");
e.printStackTrace();
}
return ips;
}
Lien : http://java.sun.com/j2se/1.4/docs/api/java/net/InetAddress.html
La première solution consiste à préciser le proxy au démarrage de la JVM, idéale si une application ne gère pas cette option...
java -DproxySet=true -DproxyHost=nomproxy -DproxyPort=numport test
Properties prop = System.getProperties();
prop.put("http.proxyHost","172.28.48.1");
prop.put("http.proxyPort","8080");
Si vous avez besoin de vous authentifier sur le proxy avec un user/mot de passe, il faut utiliser la classe Authenticator pour indiquer ces informations. Il suffit pour d'utiliser la méthode setDefault(Authenticator a) avec un Authenticator personnel :
Authenticator.setDefault(new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("user", "password".toCharArray());
}
});
Pour faire cela, on doit récuperer l'URLConnection correspondant à l'URL. Par exemple :
public void doPost(String adresse){
OutputStreamWriter writer = null;
BufferedReader reader = null;
try {
//encodage des paramètres de la requête
String donnees = URLEncoder.encode("clef", "UTF-8")+
"="+URLEncoder.encode("valeur", "UTF-8");
donnees += "&"+URLEncoder.encode("autreClef", "UTF-8")+
"=" + URLEncoder.encode("autreValeur", "UTF-8");
//création de la connection
URL url = new URL(adresse);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
//envoi de la requête
writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(donnees);
writer.flush();
//lecture de la réponse
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String ligne;
while ((ligne = reader.readLine()) != null) {
System.out.println(ligne);
}
}catch (Exception e) {
e.printStackTrace();
}finally{
try{writer.close();}catch(Exception e){}
try{reader.close();}catch(Exception e){}
}
}
Il existe différentes façons pour établir une communication entre une applet et une servlet. Les deux méthodes suivantes ne sont pas propres aux servlets, et peuvent être aussi utilisées entre 2 applications quelconques.
- RMI : permet de manipuler des objets distants (plus d'infos ici)
- Socket : création d'un flux point à point (plus d'infos ici)
La méthode la plus proche du mode de fonctionnement d'une httpServlet est une communication HTTP; elle a l'avantage d'utiliser (en général) le port 80, et donc de franchir plus facilement les firewalls. La requête HTTP de l'applet peut se faire soit par GET, soit par POST (multipart).
/** Envoi de données par GET */
URL url = new URL("http://localhost/servlet?cle1=valeur1&cle2=valeur2");
URLConnection conn = url.openConnection();
/** Envoi de données par POST */
URL url = new URL("http://localhost/servlet");
String data = "cle1=valeur1&cle2=valeur2");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream());
osw.write(data);
osw.flush();
osw.close();
/** Récupération de la réponse de la servlet */
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
/** traitement des lignes */
} br.close();
Pour envoyer la réponse à partir de la servlet, il suffit d'utiliser l'OutputStream de l'HttpServletResponse.
/** Réponse de la servlet */
String texte = "...";
PrintStream out = new PrintStream(response.getOutputStream());
out.println(texte);
out.close();
Remarque: pour le passage des données (clés ou valeurs), si des caractères spéciaux sont employés, utiliser URLEncoder :
cle1 = URLEncoder.encode(cle1, "UTF-8")
Depuis la version 5.0 du jdk, la machine virtuelle a introduit un mécanisme de sélection automatique de serveur proxy lors de la connection au réseau.
Ce mécanisme qui devrait être totalement transparent est malheureusement entaché de quelques bugs problématiques.
Le premier d'entre eux touche particulièrement les machines Windows qui utilise le protocole NetBIOS, et provoque des connections réseaux anormalement longues (environ 5 secondes par connection).
Pour pallier à ce bug, il est possible de désactiver ce comportement en utilisant la classe ProxySelector :
ProxySelector.setDefault(null);
Mais un second bug peut alors posé problème. Alors que le code ci-dessus est parfaitement valable, ce dernier peut provoquer un NullPointerException lors de la connection.
Le premier de ces bugs a été corrigé dans l'update 6 de Java 5.0, alors que le second semble avoir été introduit dans une version ultérieure pour n'être corrigé que dans les premières versions de Mustang (Java SE 6).
Ainsi, pour éviter tout problème quel que soit la JVM cliente utilisée, il est neccessaire de vérifier la version exacte de la JVM avant d'utiliser le code ci-dessus, ce qui pourrait donner :
// Si on utilise une JVM 1.5
if ( "1.5".equals(System.getProperty("java.specification.version")) ) {
// On récupère le numéro exacte de l'update (en supprimant le numéro de version majeure) :
String update = System.getProperty("java.version").replaceAll("^1.5.0_", "");
try {
// Si on utilise une JVM antérieure à l'update 6
if (Integer.parseInt(update)<6) {
ProxySelector.setDefault(null);
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
Bien entendu, si votre application utilise Java 6 (ou supérieur) tout ceci est complètement inutile.
Lien : [Bug ID: 5092063] Extremely slow socket creation using new Socket("ip-address", port)
Lien : [Bug ID: 6215885] URLConnection.openConnection NPE if ProxySelector.setDefault is set to null


















