Exemple d'application client/serveur, comment instaurer un "dialogue" ?
3 réponses
Francois
Bonjour à tous,
Je suis en train d'apprendre à faire une petite application
client/serveur en ligne de commande toute bête.
On lance le serveur qui est une sorte de madame Soleil,
c'est-à-dire qu'elle va afficher une prédiction au client.
Autrement dit, une fois que le serveur tourne, quand je
lance un client, une prédiction envoyée par le serveur
s'affiche sur la console du client (la prédiction est une
chaine choisie au hasard dans une liste de chaines).
public void go() {
try {
Socket s = new Socket("127.0.0.1", 4242);
InputStreamReader isr = new
InputStreamReader(s.getInputStream());
BufferedReader lecture = new BufferedReader(isr);
String prediction = lecture.readLine();
System.out.println("La prédiction est : " +
prediction);
lecture.close();
} catch(IOException ex) {
System.out.println("Désolé, pas de connexion
possible...");
}
}
public static void main(String[] args) {
Client client = new Client();
client.go();
}
}
//--------------------------------------
et le serveur
//--------- le serveur-------------------
import java.io.*;
import java.net.*;
public class MadameSoleilServeur {
String[] listePredictions = {"Vous êtes un homme.",
"Vous êtes une femme.",
"Vous êtes riche." };
public String getPrediction() {
int random = (int) (Math.random() *
listePredictions.length);
return listePredictions[random];
}
public void go() {
try {
ServerSocket serverSock = new ServerSocket(4242);
while(true) {
Socket sock = serverSock.accept();
String prediction = this.getPrediction();
PrintWriter ecriture = new
PrintWriter(sock.getOutputStream());
ecriture.println(prediction);
ecriture.close();
System.out.println("Envoie du message : " +
prediction);
}
} catch(IOException ex) {
System.out.println("Désolé, pas de connexion
possible...");
}
}
public static void main(String[] args) {
MadameSoleilServeur serveur = new
MadameSoleilServeur();
serveur.go();
}
}
//------------------------------------
Le code fonctionne mais je coince sur ceci : comment faire
pour qu'il y ait un "vrai dialogue" entre le client et le
serveur ? Je veux dire par là que dans mon exemple
finalement pas de vrai dialogue : le client se connecte au
serveur et le serveur envoie sa prédiction. Par exemple,
j'aimerais qu'il soit proposé au client "Cette prédiction
vous convient-elle, oui ou non ?" et que si la réponse est
"non" le serveur renvoie une prédiction, jusqu'à ce que le
client dise "oui". Mais je ne sais pas comment faire.
Comment dire au serveur "une fois que tu as envoyé ta
prédiction, attends la réponse du client" etc...
Je pense qu'il doit me manquer des connaissances, si je
pouvais avoir quelques pistes ce serait bien. Mon exemple
est bien sûr sans intérêt, c'est juste pour comprendre un
peu le principe d'une application client/serveur.
Je cite : « When a connection is requested and successfully established, the accept method returns a new Socket object which is bound to the *same local port* and has it's remote address and remote port set to that of the client. »
Je ne comprends pas "the same local port". Je croyais au contraire que la méthode "accept" renvoyait un objet socket sur un port *différent* du ServerSocket d'écoute pour que justement le ServerSocket puisse continuer à faire son travail d'écoute ? Ou alors mon anglais (assez pauvre) me joue des tours.
public static void main(String[] args) throws IOException {
Socket clientSocket = null; PrintWriter out = null; BufferedReader in = null;
try { clientSocket = new Socket("127.0.0.1", 4242); out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); } catch (UnknownHostException e) { System.err.println("Impossible de contacter le serveur."); System.exit(1); } catch (IOException e) { System.err.println("Impossible d'obtenir I/O venant du serveur."); System.exit(1); }
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Voulez vous une prédiction, oui ou non ? "); String userInput = stdIn.readLine(); out.println(userInput); while (!userInput.equals("non")) { System.out.println("Voici la prédiction : " + in.readLine()); System.out.print("Encore une autre, oui ou non ? "); userInput = stdIn.readLine(); out.println(userInput); }
Je trouve que ce n'est pas facile ce couplage entre le client et le serveur, ça rend les choses deux fois plus compliquées : quand je code le client je dois avoir le serveur en tête et inversement. Y a-t-il des moyens pour faire des dialogues client/serveur avec un code plus facile à appréhender. Peut-être des factorisations de codes, une classe que pourraient avoir le client et le serveur en commun ?
Merci pour votre aide.
-- François Lafont
Xavier Nayrac a écrit :
Tu devrais trouver ton bonheur par ici :
http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
Merci ça m'a aidé effectivement, notamment l'exemple complet
du client.
Mais je ne comprends pas cette phrase dans cette page :
http://java.sun.com/docs/books/tutorial/networking/sockets/clientServer.html
Je cite : « When a connection is requested and successfully
established, the accept method returns a new Socket object
which is bound to the *same local port* and has it's remote
address and remote port set to that of the client. »
Je ne comprends pas "the same local port". Je croyais au
contraire que la méthode "accept" renvoyait un objet socket
sur un port *différent* du ServerSocket d'écoute pour que
justement le ServerSocket puisse continuer à faire son
travail d'écoute ? Ou alors mon anglais (assez pauvre) me
joue des tours.
public static void main(String[] args) throws IOException {
Socket clientSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
clientSocket = new Socket("127.0.0.1", 4242);
out = new
PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Impossible de contacter le
serveur.");
System.exit(1);
} catch (IOException e) {
System.err.println("Impossible d'obtenir I/O
venant du serveur.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new
InputStreamReader(System.in));
System.out.print("Voulez vous une prédiction, oui
ou non ? ");
String userInput = stdIn.readLine();
out.println(userInput);
while (!userInput.equals("non")) {
System.out.println("Voici la prédiction : " +
in.readLine());
System.out.print("Encore une autre, oui ou non ? ");
userInput = stdIn.readLine();
out.println(userInput);
}
Je trouve que ce n'est pas facile ce couplage entre le
client et le serveur, ça rend les choses deux fois plus
compliquées : quand je code le client je dois avoir le
serveur en tête et inversement. Y a-t-il des moyens pour
faire des dialogues client/serveur avec un code plus facile
à appréhender. Peut-être des factorisations de codes, une
classe que pourraient avoir le client et le serveur en commun ?
Je cite : « When a connection is requested and successfully established, the accept method returns a new Socket object which is bound to the *same local port* and has it's remote address and remote port set to that of the client. »
Je ne comprends pas "the same local port". Je croyais au contraire que la méthode "accept" renvoyait un objet socket sur un port *différent* du ServerSocket d'écoute pour que justement le ServerSocket puisse continuer à faire son travail d'écoute ? Ou alors mon anglais (assez pauvre) me joue des tours.
public static void main(String[] args) throws IOException {
Socket clientSocket = null; PrintWriter out = null; BufferedReader in = null;
try { clientSocket = new Socket("127.0.0.1", 4242); out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); } catch (UnknownHostException e) { System.err.println("Impossible de contacter le serveur."); System.exit(1); } catch (IOException e) { System.err.println("Impossible d'obtenir I/O venant du serveur."); System.exit(1); }
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Voulez vous une prédiction, oui ou non ? "); String userInput = stdIn.readLine(); out.println(userInput); while (!userInput.equals("non")) { System.out.println("Voici la prédiction : " + in.readLine()); System.out.print("Encore une autre, oui ou non ? "); userInput = stdIn.readLine(); out.println(userInput); }
Je trouve que ce n'est pas facile ce couplage entre le client et le serveur, ça rend les choses deux fois plus compliquées : quand je code le client je dois avoir le serveur en tête et inversement. Y a-t-il des moyens pour faire des dialogues client/serveur avec un code plus facile à appréhender. Peut-être des factorisations de codes, une classe que pourraient avoir le client et le serveur en commun ?
Je cite : « When a connection is requested and successfully established, the accept method returns a new Socket object which is bound to the *same local port* and has it's remote address and remote port set to that of the client. »
Tu devrais trouver ton bonheur par ici :
http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
[...]
Je cite : « When a connection is requested and successfully
established, the accept method returns a new Socket object which is
bound to the *same local port* and has it's remote address and remote
port set to that of the client. »
Je cite : « When a connection is requested and successfully established, the accept method returns a new Socket object which is bound to the *same local port* and has it's remote address and remote port set to that of the client. »