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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
| import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class DemoSocket {
private static final int PORT = 56565; // le port d'écoute du serveur
private static final String COMMANDE_FIN = "au revoir"; // la commande pour arrêter le thread serveur
private static final Scanner SCANNER = new Scanner(System.in); // un scanner pour lire les entrées de l'utilisateur
public static void main(String[] args) {
try {
lanceServer();
lanceClient();
}
catch(IOException e) {
e.printStackTrace();
}
}
private static void lanceClient() throws UnknownHostException, IOException {
boolean running=true;
do {
System.out.println("CLIENT> Entrez un message pour le serveur (vous pouvez entrer plusieurs lignes).");
System.out.println("CLIENT> Terminez par une ligne vide pour envoyer.");
System.out.println("CLIENT> Envoyer le message "+COMMANDE_FIN+" pour terminer.");
System.out.print("CLIENT> ");
System.out.flush();
String userInput = SCANNER.nextLine();
if ( !userInput.trim().isEmpty() ) { // j'ignore quand l'utilisateur ne tape rien ou que des whitespaces
final StringBuilder messageBuilder = new StringBuilder(); // je construis un message multi-ligne
while( !userInput.trim().isEmpty() ) {
if ( messageBuilder.length()!=0 ) {
messageBuilder.append("\n");
}
messageBuilder.append(userInput);
//if ( SCANNER.hasNextLine() ) {
userInput = SCANNER.nextLine();
/*}
else {
userInput = "";
}*/
}
final String message = messageBuilder.toString();
System.out.println("CLIENT> Envoi message au serveur... ("+message.length()+ " caractère"+(message.length()>1?"s":"")+" à envoyer");
try(Socket client = new Socket("localhost",PORT)) {
ecrire(client, message); // j'envoie le message au serveur
final String reponse = lire(client); // je lis la réponse du serveur
System.out.println("CLIENT> Le serveur a répondu : ");
System.out.println(reponse);
}
if ( COMMANDE_FIN.equalsIgnoreCase(message) ) { // arrêt du client
running=false;
}
}
} while(running);
System.out.println("CLIENT> Fin programme.");
}
private static void lanceServer() {
new Thread(()-> runServer()).start(); // j'exécute le serveur dans un thread
}
private static void runServer() {
try(ServerSocket server = new ServerSocket(PORT)) { // je créé un serveur
boolean running=true;
do {
try {
try(final Socket socket = server.accept()) { // bloque le thread en attendant qu'un client se connecte
System.out.println("SERVEUR> Un client s'est connecté...");
final String messageClient = lire(socket);
System.out.println("SERVEUR> Le client a envoyé : ");
System.out.println(messageClient);
System.out.flush();
if ( COMMANDE_FIN.equalsIgnoreCase(messageClient) ) { // si le client envoie la commande de fin, alors arrêt du serveur
running=false;
ecrire(socket, "Demande arrêt serveur... OK.");
}
else {
final String pluriel = messageClient.length()>1?"s":"";
ecrire(socket, "Message bien reçu. "+messageClient.length()+" caractère"+pluriel + " reçu"+pluriel);
}
}
} catch (IOException e) {
e.printStackTrace();
}
} while (running);
} catch (IOException e1) {
e1.printStackTrace();
}
}
private static String lire(Socket socket) throws IOException {
// attention on ne ferme le reader, parce que ça ferme la socket aussi (on ne pourrait plus écrire la réponse ensuite)
final BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); // j'ouvre le flux input qui me permet de récupérer ce que le client envoie
final StringBuilder sb=new StringBuilder(); // je vais concaténer tout ce que le client envoie
for(int read = reader.read(); read!=-1 && '\0'!=read ; read=reader.read()) { // je lis dans le flux dans qu'il y a quelque chose à lire, ou qu'on m'envoie pas \0 (fin de message)
sb.append((char)read); // j'accumule les caractères lu (sauf le \0)
}
return sb.toString();
}
/**
* Envoyer un message sur la socket
* @param socket
* @param string
* @throws IOException
*/
private static void ecrire(Socket socket, String string) throws IOException {
// attention on ne ferme pas le writer, parce que ça ferme la socket aussi (on ne pourrait plus écrire la réponse ensuite)
// on peut utiliser un PrintWriter à la place du BufferedWriter, si ou veut pouvoir écrire dans le writer comme on le ferait avec System.out
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));//j'ouvre le flux output qui me permet d'écrire vers l'"autre côté" (client ou serveur selon)
writer.write(string);
writer.write('\0'); // j'envoie quelque chose qui permet au récepteur de savoir que j'ai envoyé tout mon message
writer.flush(); // je force le vidage du buffer pour envoi
}
} |
Partager