bloquage d'un client de chat (socket et thread)

taoufik109
bloquage d'un client de chat (socket et thread)

salut, je develope un petit chat client serveur en java, dans ce chat le client dés qu'il se connecte il récupere la liste des utilisateurs connectés de puis le serveur et remplie une jlist avec la liste, le probleme c'est que le client se bloque apres qu'il consulte le serveur, voila le code client et serveur, et merci pour l'aide.

si vous avez des idées pour faire cela autrement, elles sont lesbienvenue.

code serveur:

Thread threadlistpseudo=new Thread()
                    {
                        public PrintWriter out=null;
                        public BufferedReader in=null;
                        public ServerSocket sEcoute=null;
                        public Socket sService=null;
                        
                        public void run()
                        {
                            ////////repondre a la requete du client pour lui communiquer la liste des pseudo
                            try{
                                    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
                                    con = DriverManager.getConnection(url);
                                    stm = con.createStatement();
                                    sEcoute =new ServerSocket(3500);
                                    sService=sEcoute.accept();
                                    out=new PrintWriter(sService.getOutputStream(),true);
                                    in=new BufferedReader(new InputStreamReader(sService.getInputStream()));
                                    
                                    String query=in.readLine();
                                    rst=stm.executeQuery(query);
                                    
                                    while(rst.next())
                                    {
                                        out.write(rst.getString(1)+ "\r\n");
                                        out.flush();
                                    }
                                    out.flush();
                                    sEcoute.close();
                                
                            }catch(Exception ex){System.out.println(ex.getMessage());}
                        }
                    };
                    threadlistpseudo.start();
 

code client:

public void windowOpened(java.awt.event.WindowEvent e) {
            ///////requete pour demander la liste des connectés depuis le serveur
                try {
                    ///state='c' =>connecté
                    String req1="select login from authentification where state='c'";
                    sClient =new Socket("localhost",3500);
                    out=new PrintWriter(sClient.getOutputStream(),true); 
                    out.write(req1+ "\r\n"); 
                    out.flush();
                    
                    in=new BufferedReader(new InputStreamReader(sClient.getInputStream()));
                    String req=in.readLine();
                    DefaultListModel dlm=new DefaultListModel();
                    lpseudo.setModel(dlm);
                    while(req!=null)
                    { 
                        req=in.readLine();  
                        lpseudo.setModel(dlm);
                        dlm.addElement(req);    
                        lpseudo=new JList(dlm);        
                    }
                    sClient.close();
                } catch (Exception ex) {System.out.println(ex.getMessage());
}
 
fredericmazue

Je n'ai pas regardé attentivement ton code par manque de temps :oops:
Mais je dirais qu'il ne bloque pas. Il fait ce que tu lui demandes, c'est à dire lire des lignes en boucle depuis un flux. Donc il lit toutes les lignes et lorsque tout est lu il lit la ligne suivante, c'est à dire celle qui va arriver (si elle arrive un jour ;) ); Donc ton client n'est pas bloqué mais en attente.

Pour obtenir ce que tu veux, tu dois tester la présence de quelque chose à lire dans le flux avant de lire.

Par exemple:


while(req!=null && in.available() != 0) 
{ 
   req=in.readLine();  
   lpseudo.setModel(dlm); 
   dlm.addElement(req);    
   lpseudo=new JList(dlm);        
} 


taoufik109

ça me donne pas la possibilité d'écrire in.available(), j'ai essayé avec in.readLine() != null , mais sans résultat.

fredericmazue

Mais si...

null certainement pas puisque available retourne un entier.

available c'est une méthode de bas niveau. Tu l'as dans les Stream, pas dans les Reader qui sont des classes de plus haut niveau.
Faut adapter un peu ton code (je te rapelle que je ne l'avais pas lu en détail).

Donc quelque chose comme:


InputStream is = sClient.getInputStream()
in=new BufferedReader(new InputStreamReader(is);
//etc
// etc
 
while(req!=null && is.available()) // is hein ? pas in :)
{
// etc, etc
} 



taoufik109

j'ai changé le code comme vous avez dit, mais cette fois ci, il remplie la jlist avec un seul enregistrement, avant il me ramene tous les enregistrements moins un, mais cette fois il me ramene qu'un seul ligne.
autre chose, lorsque je lance un deuxieme client, il me ramene rien.

s'il vous plait essayer de voir le code en détail, parcque je suis pressé par le temps et je dois rendre le projet le plus tot possible parceque j'ai déja depasser les délais

InputStream is = sClient.getInputStream();
in=new BufferedReader(new InputStreamReader(is));
String req=in.readLine();
DefaultListModel dlm=new DefaultListModel();
lpseudo.setModel(dlm);
                    while(req!=null && is.available() != 0)
                    {  
                    	req=in.readLine();  
                    	lpseudo.setModel(dlm);
                        dlm.addElement(req);    
                        lpseudo=new JList(dlm);		           
                    }
Niroken

Hello,

J'ai bien regardé ton code et il n'y a "aucun" problème pour la partie réseau.

En fait comme ton serveur ferme bien sa connexion après avoir envoyé ttes ses lignes, même si le client reste en mode "read" avec in "in.readLine()", le fait de fermer la connexion va lui faire lancer une SocketException "Connexion reset"

La ou ca ne va pas par contre c est quand tu ajoutes tes éléments dans la liste coté client (Extrait de ton code):

String req=in.readLine(); 
DefaultListModel dlm=new DefaultListModel(); 
lpseudo.setModel(dlm); 
while(req!=null) 
{ 
     req=in.readLine();  
     lpseudo.setModel(dlm); 
     dlm.addElement(req);    
     lpseudo=new JList(dlm);        
}

dlm représente ta liste mais tu lis d'abord un élément que tu n'ajoutes pas à ta liste.

A la louche je dirais que le code corrigé doit etre celui ci (sans tester):

String req=in.readLine(); 
DefaultListModel dlm=new DefaultListModel(); 
lpseudo.setModel(dlm); 
// ici on ajoute le premier élément
dlm.addElement(req);  
while(req!=null) 
{ 
     req=in.readLine();  
     lpseudo.setModel(dlm); 
     dlm.addElement(req);    
     lpseudo=new JList(dlm);        
}

Pour le deuxième point, si tu relances un client il ne se passe rien, c est normal puisque ton instance de serveur une fois qu elle a fini son boulot, elle s arrete.

Pour que ca marche il faudrait que tu lances en boucle des instances de ton Thread serveur.

Bonne chance,
Niroken

taoufik109

j'ai essayé avec

lpseudo.setModel(dlm);
dlm.addElement(req); 
                    while(req!=null && is.available() != 0)
                     {   
                    	req=in.readLine();  
                    	lpseudo.setModel(dlm);
                        dlm.addElement(req);     
                        lpseudo=new JList(dlm);	
                        
                        System.out.println("listPseudo: "+ dlm);                
                    }
		//sClient.close();

mais cette fois il m'affiche un nombre aléatoire d'enregistrement parfois 2 ou 4 ou 5, je sais pas pourqoui
pour le thread serveur j'ai ajouté une boucle while(true) et ca marche, je peux lancer plusieurs clients maintenant sans problemes

mais s'il vous plait qi vous avez une solution pour le premier probleme, ca sera un grand plaisir pour moi

Niroken

Hello,

Voici ce qu'il se passe :
- Ton instance serveur écrit dans le flux sortant attaché à la socket ouverte... puis une fois qu'elle a fini, le thread meurt et la socket se ferme, sans se soucier de ce qui a été lu coté client.
- Ton instance client lit à son rythme sur le flux entrant lié à la socket ouverte ce que le serveur lui envoit, le hic c'est que si la socket est fermé avant que le client aie tt lu, et bien tu vas avoir une exception qui va ressortir.

Ce que je te suggère, c'est d'implémenter une mini conversation client-serveur. dès que le serveur envoie une ligne, le client lui en renvoit une pour dire qu'il la bien lu, de cette facon quand le serveur fermera la socket, le client aura bien tt recu.

Coté implémentation, ca donnerait qq chose comme ca :

Cote client :

BufferedReader in=new BufferedReader(new InputStreamReader(sClient.getInputStream())); 
            String req=in.readLine(); 
            System.out.println(req);
            DefaultListModel dlm=new DefaultListModel(); 
            JList lpseudo = new JList(); 
            // ici on ajoute le premier élément 
            dlm.addElement(req);
            out.write("OK\r\n"); 
            out.flush();
            while(req!=null) 
            { 
                try {
                    req=in.readLine();
                    out.write("OK\r\n"); 
                    out.flush();
                    dlm.addElement(req);
                    System.out.println(req);  
                } catch (SocketException e) {
                    // On met req a null pour sortir de la 
                    // boucle si le serveur interromp la connexion
                    req = null;
                }
            }
            
            lpseudo.setModel(dlm);
            System.out.print(lpseudo.getModel().getSize());
            
            sClient.close(); 

Cote serveur :
while(rst.next()) 
{ 
    out.write(rst.getString(1)+ "\r\n"); 
    out.flush();
    in.readLine(); 
} 
out.flush(); 
sEcoute.close(); 

Bonne chance,
Niroken

taoufik109

j'ai changé le code avec ce ke vous avez proposé, ca affiche tous les utilisateurs au niveau System.out.println(req); mais le client est bloqué et il affiche rien, j'ai essayé le truc de inputstream mais ca marche pas.
j'ai trouvé des suggestions ki disent qu'il faut séparer les threads, une pour l'ecriture et l'autre pour l'ecture, si vous avez des idées pour résoudre ce probleme, surtt pour cette idée de séparer les threads ?

Niroken

Hello,

Juste pour etre sur : j'ai mis des System.out.println() juste pour tester l affichage, est ce qu'il écrit bien le dernier

System.out.print(lpseudo.getModel().getSize()); 

?????

Sinon pour mon test, j'ai crée deux classes distinctes Une qui contient le code serveur, une autre qui contient le code client, je les ai lancé et ca a marché, c'est a dire que j'ai affiché la taille de la liste.

Bon sinon je vais te faire un petit code qui s occupe de faire ca.

Bonne chance,
Niroken

Niroken

Hello,

Voici un code complet qui marche : (je n'ai pas mis de connexion à une base de données tu feras ca)

import graphic.JListViewer;


public class JListViewerLauncher {

    /**
     * @param args
     */
    public static void main(String[] args) {
        new JListViewer();
    }

}

package graphic;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;

import net.ProcessClient;

public class JListViewer  extends JFrame {
    
    private static final long serialVersionUID = 1L;
    
    public JList mList;
    
    public JListViewer() {
        setSize(200, 200);
        setLayout(new FlowLayout());
        
        mList = new JList();
        DefaultListModel vDefaultListModel = new DefaultListModel();
        vDefaultListModel.addElement("Pouet");
        vDefaultListModel.addElement("Pouet");
        mList.setModel(vDefaultListModel);
        
        JButton vButton = new JButton("Refresh");
        vButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent pE) {
                displayDatasFromServer();
            }
            
        });
        
        add(mList);
        add(vButton);
        
        setVisible(true);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    }
    
    private void displayDatasFromServer() {
        Thread vThread = new Thread() {
            
            public void run () {
                try {
                    mList.setModel(new ProcessClient().getDatasFromServer());
                } catch (Exception e) {
                    e.printStackTrace();
                }                
            }
            
        };
        vThread.start();
    }
    
}

package net;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;

import javax.swing.DefaultListModel;

public class ProcessClient {
    
    public DefaultListModel getDatasFromServer() throws Exception {
        DefaultListModel vResult = new DefaultListModel();
               
        Socket vClientSocket = new Socket("localhost",3500); 
        OutputStream vClientOutputStream = vClientSocket.getOutputStream();
        InputStream vClientInputStream = vClientSocket.getInputStream();
        
        PrintWriter vOutputPrintWriter = new PrintWriter(vClientOutputStream,true); 
        BufferedReader vInputBufferedReader = new BufferedReader(new InputStreamReader(vClientInputStream)); 
        String vLineFromServer = null;
        //Debbut de la conversation client-serveur
        writeLineInPrintWriter(vOutputPrintWriter, "OK");
        vLineFromServer = vInputBufferedReader.readLine();
        vResult.addElement(vLineFromServer);
        writeLineInPrintWriter(vOutputPrintWriter, "OK");
        
        while(vLineFromServer!=null) { 
            try {
                vLineFromServer = vInputBufferedReader.readLine();
                vResult.addElement(vLineFromServer);
                writeLineInPrintWriter(vOutputPrintWriter, "OK");
            } catch (SocketException e) {
                // On met vLineFromServer a null pour sortir de la 
                // boucle si le serveur interromp la connexion
                vLineFromServer = null;
                e.printStackTrace();
            }
        }
        
        vClientSocket.close(); 
                
        return vResult;
    }
    
    private void writeLineInPrintWriter(PrintWriter pPrintWriter, String pMessage) {
        if (pPrintWriter != null) {
            pPrintWriter.write(pMessage + System.getProperty("line.separator"));
            pPrintWriter.flush();
        }
    }
    
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


public class ProcessServer {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Thread threadlistpseudo=new Thread() 
        { 
            public PrintWriter out=null; 
            public BufferedReader in=null; 
            public ServerSocket sEcoute=null; 
            public Socket sService=null; 
            
            public void run() 
            { 
                try { 
                        sEcoute =new ServerSocket(3500); 
                        sService=sEcoute.accept(); 
                        out=new PrintWriter(sService.getOutputStream(),true); 
                        in=new BufferedReader(new InputStreamReader(sService.getInputStream())); 
                        
                        String query=in.readLine(); 
                        System.out.println(query);
                        
                        for (int i = 0; i < 10; i++) {
                            out.write(i + "Pouet\r\n");
                            out.flush(); 
                            in.readLine();
                        }
                        
                        out.flush(); 
                        
                        sEcoute.close(); 
                    
                } catch(Exception ex) {
                    ex.printStackTrace();
                } 
            } 
        }; 
        threadlistpseudo.start(); 


    }

}

Bonne chance,
Niroken

taoufik109

je suis vraiment desolé, j'ai essayé d'implementer ton code mé j'ai pa arriver, est ce ke tu peux adapter le code totalement a mon projet ?

Niroken

Hello,

Hmm, as tu réussi à faire fonctionner mon code déjà?(indépendamment de la partie connexion base de données).

Si oui : je te posterais un code dans lequel tu pourras facilement implémenter une connexion à la base de données.

Si non : j'aimerais bien comprendre ce qui t as bloqué..... avant d'implémenter autre chose.

Bonne chance,
Niroken

Niroken

Hello,

Tout d'abord mille excuses, j'ai raconté une grosse c...... :)

Ce qui m'avait troublé dans tout ca c'était le fait que ton client n'affiche à un moment donné qu'une partie ou pas du tt de données, et que le nombre de lignes affichées pouvait être aléatoire.

J'ai donc pensé que c'était parcequ'une fois que le serveur avait tout envoyé il se fermait et le client pouvait ne pas avoir tt lu.

C'est donc pourquoi je me suis dis... le client va dire au serveur a chaque ligne qu il la bien recu, de cette facon une fois que le serveur va fermer sa connexion on est sur que le client a bien tt recu.

Le hik c'est que j'ai refait un test et je n'obtenais pas la même chose, et je me suis apercu, que dans ton code serveur tu faisais :

sEcoute.close();

au lieu de
sClient.close();

Je me suis basé la dessus et tout le problème venait de la. Ce n'était pas la bonne socket que tu as fermé. Du coup dans mes précédents posts je t'ai proposé une usine à gaz, qui marche certes mais qui n'est pas super performante(bcp d envois reception de données inutiles).

Du coup je me rebase sur ce que tu avais fait précédemment et ca donne :

Code serveur :

Thread threadlistpseudo=new Thread() 
                    { 
                        public PrintWriter out=null; 
                        public BufferedReader in=null; 
                        public ServerSocket sEcoute=null; 
                        public Socket sService=null; 
                        
                        public void run() 
                        { 
                            ////////repondre a la requete du client pour lui communiquer la liste des pseudo 
                            try{ 
                                    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
                                    con = DriverManager.getConnection(url); 
                                    stm = con.createStatement(); 
                                    sEcoute =new ServerSocket(3500); 
                                    sService=sEcoute.accept(); 
                                    out=new PrintWriter(sService.getOutputStream(),true); 
                                    in=new BufferedReader(new InputStreamReader(sService.getInputStream())); 
                                    
                                    String query=in.readLine(); 
                                    rst=stm.executeQuery(query); 
                                    
                                    while(rst.next()) 
                                    { 
                                        out.write(rst.getString(1)+ "\r\n"); 
                                    } 
                                    out.flush(); 
                                    sClient.close();
                                    // et non sEcoute.close(); 
                                
                            }catch(Exception ex){System.out.println(ex.getMessage());} 
                        } 
                    }; 
                    threadlistpseudo.start(); 

Code client :

try { 
            ///state='c' =>connecté 
            String req1="select login from authentification where state='c'"; 
            Socket sClient =new Socket("localhost",3500); 
            PrintWriter out=new PrintWriter(sClient.getOutputStream(),true); 
            out.write(req1+ "\r\n"); 
            out.flush(); 
            
            BufferedReader in=new BufferedReader(new InputStreamReader(sClient.getInputStream())); 
            String req=new String(); 
            DefaultListModel dlm=new DefaultListModel(); 
            while((req=in.readLine()) != null) {
                dlm.addElement(req);
            } 
            JList lpseudo = new JList(dlm);
            System.out.println(dlm.getSize());
            sClient.close(); 
        } catch (Exception ex) {ex.printStackTrace();} 

Bonne chance et dsl encore,
Niroken

taoufik109

tu voulais dire sService.close() au lieu de sEcoute.close(), j'ai essayé mé ca marche pa, au niveau System.out.println(req) il affiche la liste mé dans la jliste il affiche rien.

Niroken

Hello,

Quote:

au niveau System.out.println(req) il affiche la liste mé dans la jliste il affiche rien.

Dans ce cas c est autre chose, si tu récupères les données quand tu les affiches, le client a bien fait son boulot, c'est au niveau de la couche graphique que ca ne va pas.

Bon je te passe la un code qui fonctionne de mon coté, j'ai réimplémenté le serveur et le client en gros quand tu charges ta fenetre client et que le serveur est lancé... le serveur envoit n fois "Pouet" puis il incrémente n de 1 comme ca quand tu cliques sur refresh, tu affiches un élément de plus à chaque fois.

Pour mettre ta partie base de données il faudra que tu modifies légérement la méthode sendDatasToClient()

Code Serveur :

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


public class ProgramServer {

	public static int sNbBoucle = 4;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new ProgramServer().launchServer();
	}
	
	public void launchServer() {
    	try {
			ServerSocket vServerSocket = new ServerSocket(3500);
			while(true) {
				final Socket vSocket = vServerSocket.accept();
				
				Thread vThread = new Thread() {
					
					public void run() {
						try {
							sendDatasToClient(vSocket);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					
				};
				
				vThread.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    
    private void sendDatasToClient(Socket pSocket) throws Exception {
    	// A mettre ici l appel pour la base de donnees.
    	PrintWriter vOutputPrintWriter = new PrintWriter(pSocket.getOutputStream(),true);; 
        BufferedReader vInputBufferedReader = new BufferedReader(new InputStreamReader(pSocket.getInputStream()));
        String vDatasFromClient = vInputBufferedReader.readLine();
        
        for (int i = 0; i < sNbBoucle; i++) { 
        	vOutputPrintWriter.write(i + "Pouet\r\n");
        	vOutputPrintWriter.flush();
        }
        
        vOutputPrintWriter.flush();
        pSocket.close();
        sNbBoucle++;
    }

}

Code Client :

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;

import net.ProcessClient;


public class ProgramClient extends JFrame {
	
	private JList mList;

	public ProgramClient() {
		setSize(200, 200); 
        setLayout(new FlowLayout()); 
        
        mList = new JList(); 
                
        JButton vButton = new JButton("Refresh"); 
        vButton.addActionListener(new ActionListener() { 

            public void actionPerformed(ActionEvent pE) { 
                displayDatasFromServer(); 
            } 
            
        });
        
        addWindowListener(new WindowAdapter() {
        	
        	public void windowOpened(WindowEvent pEvent) {
        		displayDatasFromServer(); 
        	}
        	
        });
        
        add(mList); 
        add(vButton); 
        
        setVisible(true); 
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
	}

	public void displayDatasFromServer() {
		Thread vThread = new Thread() { 
            
            public void run () { 
                try { 
                	String req1="select login from authentification where state='c'"; 
                    Socket sClient =new Socket("localhost",3500); 
                    PrintWriter out=new PrintWriter(sClient.getOutputStream(),true); 
                    out.write(req1+ "\r\n"); 
                    out.flush(); 
                    
                    BufferedReader in=new BufferedReader(new InputStreamReader(sClient.getInputStream())); 
                    String req=new String(); 
                    DefaultListModel dlm=new DefaultListModel(); 
                    while((req=in.readLine()) != null) {
                        dlm.addElement(req);
                    } 
                    System.out.println(dlm.getSize());
                    sClient.close(); 
                	mList.setModel(dlm); 
                } catch (Exception e) { 
                    e.printStackTrace(); 
                }                
            } 
            
        }; 
        vThread.start(); 
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new ProgramClient();
	}

}
taoufik109

Merci infiniment pour votre aide grace a la quelle je peux maintenant recuperer ma liste des utilisateurs depuis mon serveur.

maintenant apres ke j'ai en main l'ip du destinataire , je veux communiquer directement avec ce ip sans passer par le serveur, donc mon programme dois comporter une serverSocket et socket en meme temps, mé cela me permet pa de mettre l'ip ke je veux dans la socket

ServerSocket ss;
Socket s;
ss=new ServerSocket(port);
s=ss.accept();

donc je dois declarer une autre sockt ou koi ?
fredericmazue

Quote:
je veux communiquer directement avec ce ip sans passer par le serveur

En principe la communication dans un chat passe par le serveur. Mais bon pourquoi pas ?

Quote:
mé cela me permet pa de mettre l'ip ke je veux dans la socket

Non mais tu peux tester qui s'est connecté.
accept te retourne un objet Socket. Là tu appelles getInetEddress. Et après de l'objet InetAddress tu appelles getHostAdress et là tu regardes qu'elle IP c'est. Si ça te convient tu continues, sinon tu fermes le socket.

taoufik109

apparemnt j'ai une fausse idée de communiquer directement sans passer par le serveur.

j'ai changer d'idée et je compte utiliser le serveur pour les communications entre clients, si vous avez des propositions pour le code, ca sera un grand plaisir pour moi.

Niroken

Hello,

Je te posterais un bout de code qui s'occupera de ca :) D ici la, patience :)

Niroken

taoufik109

ok, merci ppur l'aide

taoufik109

slt, j'ai essayé de rendre la communication directe entre clients sans passer par le serveur, voila le code ke j'ai écrit mé ca passe pa, je sé pa porkoi ?

public void ServFonct() {
	int port=6500;
	ServerSocket ss;
	Socket s;
	try{
		ss=new ServerSocket(port);
		while(true){
			s=ss.accept();
			InputStreamReader isr;
			isr=new InputStreamReader(s.getInputStream());
			BufferedReader in=new BufferedReader(isr);
			PrintStream out=new PrintStream(s.getOutputStream());
			//PrintWriter out1=new PrintWriter(s.getOutputStream(),true);
            String ch=in.readLine();
			trecu.append("\n>>>>  "+ch);
			out.flush();
			s.close();
		}
	}catch(IOException iu){}
}
/////////***********************
void envoyer(){
	int port=6500;
	Socket s;
	
	try{
		s=new Socket("ip",port);   ///ip je le recupere depuis le serveur
		InputStreamReader isr;
		isr=new InputStreamReader(s.getInputStream());
		BufferedReader in=new BufferedReader(isr);
		PrintWriter out1=new PrintWriter(s.getOutputStream(),true);
		String ch=tenvoi.getText();
		out1.write(ch);
		s.close();    
	}catch(IOException iu){
		System.out.println("Erreur:"+iu.getMessage());
		JOptionPane.showMessageDialog(this,"Erreur: ip not connect","Message d'erreur",JOptionPane.ERROR_MESSAGE);                                   
	}	
}
//////////////////////////////////////////
private JButton getBenvoi() {
		if (benvoi == null) {
			benvoi = new JButton();
			benvoi.setText("Envoyer");
			benvoi.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("actionPerformed()");
					envoyer();
				}
			});  
		}
		return benvoi;
	} 
//////////////////*****************************
	public static void main(String[] args) {
		new ClServ().ServFonct();
		//new ClServ().envoyer();
		
	}

je veux aussi ajouter a mes jtextarea des JScrollPane, est ce ke vous avez une idée, comment faire cela ?

Niroken

Hello,

Tout d'abord voici, un petit code qui te permet d'afficher un JTextArea dans un JScrollPane dans une fenetre.

Les barres de défilement horizontale et verticale n'apparaitront que si nécessaire.

import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class TchatWindow extends JFrame {

	private static final long serialVersionUID = 1L;
	private JTextArea mTextArea;
	
	public TchatWindow() {
		setSize(300, 300);
		setLayout(new FlowLayout());
		
		mTextArea = new JTextArea();
		
		JScrollPane vScrollPane = new JScrollPane(mTextArea);
		vScrollPane.setPreferredSize(new Dimension(100, 100));

		add(vScrollPane);
		
		setVisible(true); 
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
	}	
	
}

Sinon pour ce qui est de ta communcation client-serveur, il y a quelque chose qui ne va pas.
Tu lances le client et le serveur dans le même Thread si j'en juge ta méthode main et le fait que tes fonctions clients et serveurs ne sont pas lancées dans des Threads séparés.

En gros ce qu'il va se passer..tu lances le serveur..celui ci va bloquer au niveau de la méthode accept(). Comme le serveur est bloqué et que dans l'ordre des instructions tu lances ton client après, celui ci ne sera jamais lancé puisque le serveur est bloqué.

Donc pour commencer, je te suggère de mettre le code client et le code serveur dans deux fichiers de classes distincts avec chacun leurs propres méthodes main.

Tu lances le serveur dun coté et le client de l'autre et tu me dis ce qu'il se passe si ca tourne mal :)

Sinon je t'avais dis que je te passerais un petit exemple de Tchat client-serveur, c'est un peu plus long à implémenter que ce que j'avais pensé, je te le posterais donc d'ici la fin de la semaine :)

Bonne chance,
Niroken

taoufik109

Merci infiniment pour votre aide.

le probleme c ke je veux pa séparer client et serveur, parce ke au niveau de mon chat voici c ke je compte faire:

l'utilisateur se connecte au serveur, ce serveur sa principal fonction c'est k'il contient la base de données des utlisateurs,

si client se connecte il charge la liste des connéctés depuis ce serveur, aprés il communique directement avec un autre client a travers l'ip ki a pu récuperer depuis le serveur, donc chaque client doit jouer le role du client et serveur en meme temps pour communiquer avec un autre client, c pour ca ke j'ai met code client et serveur dans le meme fichier.

autre chose lorske je fais l'authentification ca passe mé le formulaire d'authentification reste toujours afficher, je fais :

private JButton getBenvoyer() {
doAuthentification();
client_test cl= new client_test();
cl.setVisible(true);
Authentification at=new Authentification();
at.setvisible(false);					
}   

mé ca reste toujours afficher.[/code]
fredericmazue

Quote:
si client se connecte il charge la liste des connéctés depuis ce serveur, aprés il communique directement avec un autre client a travers l'ip ki a pu récuperer depuis le serveur, donc chaque client doit jouer le role du client et serveur en meme temps pour communiquer avec un autre client, c pour ca ke j'ai met code client et serveur dans le meme fichier.

Arrête moi si je me trompe, mais si tu fais ça, rapidement tu vas avoir des serveurs désynchronisés au niveau de la liste des connectés. Pour y remédier il va falloir qu'un client se connecte à tous les serveurs systématiquement et éventuellement informe certains de ceux-ci des ajouts dans la liste des connectés. Je ne suis pas sûr que ça soit tout simple ton truc là.... Enfin je n'ai peut être pas bien compris ?

Remarque il y a un autre moyen de régler ça: écrire le tout non en Java mais en Erlang. Avec sa base de données distribuée en mémoire (Mnesia) Erlang te permettrait de faire ce que tu veux facilement. Mais c'est uen autre histoire....

Niroken

Hello,

Quote:

Remarque il y a un autre moyen de régler ça: écrire le tout non en Java mais en Erlang. Avec sa base de données distribuée en mémoire (Mnesia) Erlang te permettrait de faire ce que tu veux facilement. Mais c'est uen autre histoire....

Alala, il est très bien ce Java :D

Bon indépendamment de ca, l'avantage d un chat c'est que l'on a pas besoin de faire des conversations très rapprochées dans le temp, une conversation relancée toutes les (500 ms) est bien suffisante à mon avis.

Du coup dans ton instance serveur, tu gardes la liste des connectés, et a chaque fois qu un client envoit au serveur un potentiel nouveau message puis récupère les messages des autres clients, le serveur envoie aussi la liste actualisées des clients connectés.

De plus j'insiste lourdement sur le fait que tu ferais mieux de séparer ton code client et serveur dans au moins deux fichiers de classes distincts.

D'une part c'est plus propre, et tu as une architecture plus simple à gérer.

Un serveur qui conserve la liste des clients connectés et des nouveaux messages en attente, et les clients qui viennent faire des requetes sur ce serveur pour envoyer de nouveaux messages puis récupérer les messages et la liste des clients connectés :)

Bonne chance,
Niroken

fredericmazue

Quote:
Alala, il est très bien ce Java

Sans doute :)
Mais Erlang aussi et c'était une occasion de faire connaître autre chose.

Quote:
Du coup dans ton instance serveur, tu gardes la liste des connectés, et a chaque fois qu un client envoit au serveur un potentiel nouveau message puis récupère les messages des autres clients, le serveur envoie aussi la liste actualisées des clients connectés.

Il y a quelque chose que je ne comprends pas bien soit 4 clients/serveurs A,B, C,D.

A et B parlent entre eux C et D parlent entre eux. Comment C et D peuvent -il connaitre la présence de A et B sur le chat ? Remarque peut être que l'idée est justement que la présence de A et B ne soit pas connue :) Ou peut êtrre aussi que je n'ai rien pigé du tout :D

Niroken

Hmmm je t'avoue que pour moi il était question que A, B , C, D coomuniquent tous avec le même serveur S. et que c'est le serveur S qui renvoit les données au(x) client(s).

Dans le cas ou c'est vraiment A et B qui parlent entre eux et C et D aussi, alors on peut peut être envisager de déclarer un attribut statique dans sa classe, il sera commun à toutes les instances, ensuite ben je sais pas trop j'ai pas réfléchi :D

Niroken

fredericmazue

Quote:
Hmmm je t'avoue que pour moi il était question que A, B , C, D coomuniquent tous avec le même serveur S

Le fait est qu'un chat c'est comme ça

mais il dit bien:

Quote:
chaque client doit jouer le role du client et serveur en meme temps pour communiquer avec un autre client

J'ai compris que chaque client était aussi un serveur. Mais bon il va nous préciser son idée je pense

taoufik109

bonjour, je crois que j'etais pas clair dans mes messages, voila l'histoire complete:

j'ai une base de données access avec une table uthentification qui contient les champs: login, password, ip, statut.

a chaque fois qu'un utilisateur se connecte, je change tous simplement son statut dans la base de données serveur,
statut='c' pour un utlisateur connecté et statut='d' pour utilisateur deconnecté, et je change ausssi son ip a chaque fois qu'il se connecte.

si un nouveau utilisateur veut se connecter au chat, d'abord il passe par un formulaire d'authentification, si il n'est pas inscrit je lui donne la possibilité
d'inscription, voila une image qui traduisent ce ke j'ai dit :
http://www.monsterup.com/image.php?url=upload/1233234983.jpg

apres une bonne authentification l'interface client apparut, voila de koi s'agit il:

http://www.monsterup.com/image.php?url=upload/1233235293.jpg

a droite c la liste des utilisateurs connectés, ca veut dire ki ont le statut='c' dans la bd serveur, j'ai pa trouvé d'autre solutions pour rafraichir automatiquement cette
liste, alors j'ai ajouté une boutton pour rafraichir,

je choisit un utilisateur de la liste pour communiquer avec lui puis je récupere sans ip de la bd serveur, apres je veux communiquer directement avec
cette utilisateur puiske j'ai son ip alors c pa la peine de passer par le serveur, voila c dans cette étape ke je suis bloqué,
ce ke j'essaye de vous expliquer c ke dans la discussion entre 2 utilisateurs il ya pa de client et serveur, tous les deux se comportent comme client
et serveur c pour cela j'ai essayé d'ecrire tous le code dans le meme fichier, alors c pa la peine ke vous m'ecrire tout un code de chat client serveur
juste la partie ou je suis bloké .
Voici un lien ki contient tous le code source ke j'ai écrit juska mnt: http://up.sur-la-toile.com/im9S

je voudrais bien penser a d'autre solutions comme celle ke vous avez proposé mé le probleme c le temps.

Niroken

Hello,

J'ai regardé ton code et je dois avouer que ce n'est pas évident évident.

Ceci parce que ton choix d'architecture est on va dire "original", mais ca le rend d'autant plus compliqué.

Ceci dit parmi la liste des erreurs que j'ai pu relever non exhaustive :
- Comme tu déclares plein d'instances serveur, si tu les joues sur le même poste, il y en a qui ne peuvent démarrer puisqu elles utilisent le même port d 'écoute, je pense au 3502 notemment qui est utilisé par ta classe serveur et client.

- Dans ta classe client j'ai vu des choses du genre :

Thread vThread = new Thread() {
	           
	            public void run () {
	                try {
	                	//JOptionPane.showInputDialog("taoufik dit >>"+tenvoi.getText()+"\r\n");
	                	//String ip=displayDatasFromServerIp();
	                	ServerSocket ss=new ServerSocket(3502);
	                    Socket sc=ss.accept();
	                	Socket sClient =new Socket("192.168.1.1",3502);
Le serveur est en écoute donc les instructions suivantes ne seront pas jouées tant que le serveur n'aura pas recu de connexion de la part d'un client.....

- J'ai vu aussi que tu déconnectait ton client après l'avoir lancé :D à lafin de ton main client.

Ensuite, je fais ressortir le problème qu'avait souligné Frédéric en disant que tu devais trouver un moyen de mettre à jour ta liste de clients connectés.
Tu as résolu ca en te connectant sur ton serveur principal pour réactualiser la liste de tes clients...donc tous tes clients ont en commun d'etre connectés a ce serveur, je ne vois pas pq tu ne t en sers pas aussi pour communiquer des messages.....

Pour être franc avec toi, comme tu as dis que tu étais préssé, je pense sincèrement que reprendre le choix d'architecture que frederic et moi te proposons ira plus vite que d'essayer de continuer dans cette voie. D'autant que tes classes contiennent deja quasimment tout le code nécessaire, il suffit juste de réagencer le code, et d'en enlever un peu.
A toi de choisir...

Quote:

et serveur c pour cela j'ai essayé d'ecrire tous le code dans le meme fichier, alors c pa la peine ke vous m'ecrire tout un code de chat client serveur
juste la partie ou je suis bloké .

Je t'avais dis que je pouvais te poster un bout de code pour un Tchat client-serveur, tu n'en veux plus?

Bonne chance,
Niroken

taoufik109

wé merci, c pa la peine de vous ecrire un chat client serveur, parcke si j'arrive a résoudre le probleme dessous, c suffisant pour moi.

ok, je suis d'accord avec vous, c mieux ke les messages passent par le serveur, mé je sé pa comment faire, si vous me proposé klkc ca sera tré beau pour moi ?

Niroken

Très bien :)

Je te fournis un exemple dem1 à partir de ton code.

Niroken

taoufik109

ok, merci bcp.

taoufik109

bonjour, s'il vous plait, est ce ke vous avez trouvé des difficultés pour me fournir le code, ke vous m'avez promis pour hier, voila j'ai trouvé un code qui marche bien, j'ai essayé de l'adapter a mon application mé j'ai pa réussit, vous pouvez inspirer de ce code, et merci.

import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics;
import java.util.*;
import java.net.*;
import java.io.*;
import java.lang.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.border.*;
import javax.swing.colorchooser.*;
import javax.swing.plaf.metal.DefaultMetalTheme;
import javax.swing.plaf.metal.MetalLookAndFeel;

import javax.accessibility.*;




public class tp2
{

public static void main(String arg[])
{
JFrame win = new Fenetre();
win.show();
}
}


// la classe fenetre()
class Fenetre extends JFrame implements ActionListener
{



// le constructeur
public Fenetre()
{
// on met un titre
setTitle("Chat moi");

// on definit la taille
setSize(500, 400);

// on met un look and feel par defaut
updateLookAndFeel(metal);

// on gere l'appui sur la touche fermeture de la fenetre
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
} );

setLocation(100,100);


/******************************************************************
on indique le mode de placement des composants avec un Layout
Ici on utilise un Layout de type GridBagLayout ce qui permet
d'aligner les composants verticalement ou horizontalement, sans
qu'ils soient forcement de meme taille.
L'objet de type GridBagContraints permet d'apporter des
contraintes aux composants du Layout.

******************************************************************/

// on travaille avec des calques ou des panneaux
Container pane = getContentPane();

pane.setLayout(new GridBagLayout());

GridBagConstraints c = new GridBagConstraints();

/*****************************************************************
fill permet de déterminer s'il faut redimensionner le composant,
et ici uniquement horizontalement
******************************************************************/
c.fill = GridBagConstraints.HORIZONTAL;

/*****************************************************************
Ici on va ajouter des composants dans la fenetre. On utilise
plusieurs parametres:
- weightx:permet de redistribuer l'espace libre horizontal (s'il
y a) en fonction du "poids" du composant. Ainsi un composant
dont weightx vaudra zero n'aura pas d'espace en plus.
- gridx:indique la colonne où on place le composant
- gridy:indique la ligne où on place le composant

******************************************************************/

// permet de sauter une ligne par rapport au haut de la fenêtre
c.weightx = 0;
c.gridx = 0;
c.gridy = 0;
c.gridwidth=4;
c.gridheight=1;
JPanel p=new JPanel();
pane.add(p,c);


c.weightx = 0;
c.gridx = 0;
c.gridy = 1;
c.gridwidth=2;
c.gridheight=1;
//texte de saisie du message
JPanel labelpanel1=new JPanel();
JLabel l1=new JLabel("Ecrire le message à envoyer");
labelpanel1.add(l1);
pane.add(labelpanel1,c);

c.weightx = 0;
c.gridx = 2;
c.gridy = 1;
c.gridwidth=2;
c.gridheight=1;
// zone lecture
JPanel labelpanel2=new JPanel();
JLabel l2=new JLabel("Affichage des messages reçus");
labelpanel2.add(l2);
pane.add(labelpanel2,c);


c.fill = GridBagConstraints.BOTH;
c.weightx = 100;
c.weighty = 100;
c.gridx = 0;
c.gridy = 2;
c.gridwidth=2;
c.gridheight=1;
TextArea1=new JTextArea("");
TextArea1.setFont(new Font("TimesRoman",Font.BOLD,12));

pane.add(new JScrollPane(TextArea1),c);

c.weightx = 100;
c.weighty = 100;
c.gridx = 2;
c.gridy = 2;
c.gridwidth=2;
c.gridheight=1;
TextArea2=new JTextArea("");
TextArea2.setFont(new Font("TimesRoman",Font.ITALIC,12));

pane.add(new JScrollPane(TextArea2),c);


c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0;
c.weighty = 0;
c.gridx = 0;
c.gridy = 3;
c.gridwidth=1;
c.gridheight=1;
pane.add(new JLabel("Port:"),c);

c.weightx = 0;
c.gridx = 1;
c.gridy = 3;
c.gridwidth=1;
c.gridheight=1;
text2=new JTextField(20);
pane.add(text2,c);

c.weightx = 0;
c.gridx = 0;
c.gridy = 4;
c.gridwidth=1;
c.gridheight=1;
pane.add(new JLabel("Serveur: "),c);

c.weightx = 0;
c.gridx = 1;
c.gridy = 4;
c.gridwidth=1;
c.gridheight=1;
text3=new JTextField(20);
pane.add(text3,c);

c.weightx = 0;
c.gridx = 2;
c.gridy = 3;
c.gridwidth=1;
c.gridheight=2;
pane.add(new JLabel("Port: "),c);

c.weightx = 0;
c.gridx = 3;
c.gridy = 3;
c.gridwidth=1;
c.gridheight=2;
text4=new JTextField(20);
pane.add(text4,c);


c.weightx = 0;
c.gridx = 0;
c.gridy = 5;
c.gridwidth=2;
c.gridheight=1;
JPanel panel1=new JPanel();
button1=new JButton("< Envoyer >");
button1.setToolTipText("Cliquer ici pour envoyer le message");
button1.addActionListener(this);
panel1.add(button1);
pane.add(panel1,c);

c.weightx = 0;
c.gridx = 2;
c.gridy = 5;
c.gridwidth=2;
c.gridheight=1;
JPanel panel2=new JPanel();
button2=new JButton("Ecouter");
button2.setToolTipText("Cliquer ici pour lancer le serveur d'écoute");
button2.addActionListener(this);
panel2.add(button2);
pane.add(panel2,c);

c.weightx = 0;
c.gridx = 0;
c.gridy = 6;
c.gridwidth=4;
c.gridheight=1;
JPanel panel3=new JPanel();
button3=new JButton("Créer Socket client");
button3.setToolTipText("Cliquer ici pour créer le socket du client avant d'envoyer des messages");
button3.addActionListener(this);
panel3.add(button3);
pane.add(panel3,c);

c.weightx = 0;
c.gridx = 0;
c.gridy = 7;
c.gridwidth=4;
c.gridheight=1;
JPanel panel4=new JPanel();
JButton button4=new JButton("Quitter !");
button4.setToolTipText("Cliquer ici pour quitter le programme");
button4.addActionListener(this);
panel4.add(button4);
pane.add(panel4,c);
}

public void actionPerformed(ActionEvent e)
{
String cmd=e.getActionCommand();

if(cmd.equals("Créer Socket client"))
{

try
{

// client
Integer I1=new Integer(text2.getText());
Socket s=new Socket(text3.getText(),I1.intValue());
System.out.println("CLIENT> Socket client cree. Prêt à envoyer des messages\n");

this.button3.setText("< Socket crée >");
this.button1.setText("Envoyer");

// on cree l'objet out pour ecrire au travers du socket
out=new PrintWriter(s.getOutputStream());
}
catch(IOException ei)
{
System.out.println("\nAttention, erreur de socket\nVérifiez si le port n'est pas déjà utilisé\nVérifier le nom de la station hôte\n"+ ei+"\n");
}
}
if (cmd.equals("Quitter !"))
{
// Annulation
System.exit(0);
}

if(cmd.equals("Envoyer"))
{
out.println(TextArea1.getText());
System.out.println("CLIENT> Message envoyé au serveur\n");
// on libère la socket
out.flush();
//on réinitialise le champ du message
TextArea1.setText("");
}


if(cmd.equals("< Envoyer >"))
{
System.out.println("Il faut d'abord créer le socket avant d'envoyer un message\n");

}


if(cmd.equals("Ecouter"))
{
new Tache(TextArea2,text4);
}


}


// la fonction qui permet de changer de LookandFeel
public void updateLookAndFeel(String laf)
{
try
{
UIManager.setLookAndFeel(laf);
SwingUtilities.updateComponentTreeUI(this);
}
catch (Exception ex)
{
System.out.println("Failed loading L&F: " + laf);
System.out.println(ex);
}
}



private JTextField text2,text3,text4;
private JButton button3,button1,button2;
private JTextArea TextArea1,TextArea2;
private Tache t;
private PrintWriter out;

// Possible Look & Feels
private String mac = "com.sun.java.swing.plaf.mac.MacLookAndFeel";
private String metal = "javax.swing.plaf.metal.MetalLookAndFeel";
private String motif = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
private String windows = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";


}
class Tache extends Thread  
{
JTextArea TextArea;
JTextField text;

public Tache(JTextArea TextArea2,JTextField text4)
{
this.TextArea=TextArea2;
this.text=text4;
// on lance le thread
start();
}

public void run()
{


try
{
// on cree un thread pour le server car il est bloquant
Integer I2=new Integer(text.getText());
serv=new ServerSocket(I2.intValue());
System.out.println("SERVEUR> Socket serveur crée. En Attente de message\n");
sin=serv.accept();
BufferedReader in=new BufferedReader(new InputStreamReader(sin.getInputStream()));
boolean done=false;

while(!done)
{ TextArea.append(in.readLine()+"\n");
System.out.println("SERVEUR> Message bien reçu\n");
}
}
catch(IOException ei)
{
System.out.println("erreur "+ ei+"\n");
}
}

private Socket sin;
private ServerSocket serv;


}
Niroken

Hello,

Non rassures toi, j'ai réussit a me débrouiller, sauf que comme cela est un peu complexe.. je pense qu'on va procéder par étape.

D'une part, la base de données pour l'instant ce n'est pas une bonne idée..puisqu'elle ne fait que contenir des infos style "login" "password".
Mais créer un compte ne nous apporte rien puisqu on peut en créer un à chaque fois et comme aucune autre info n'est persistée du genre "amis ou contacts" favoris... c'est inutile.

Le serveur seul va gérer les connexions et savoir qui est connecté ou pas.

Donc la première étape, c'est justement la facon dont le serveur gère les connexions :
1) On allume le serveur en attente de connexions et garde en mémoire une liste de noms qui correspond au nom de chaque client.
2) Un client se connecte : L'utilisateur saisit un nom pour la durée de son tchat et l'envoit au serveur.
3)Le serveur recoit le nom, si le nom est deja présent dans la liste, alors le serveur dit que c'est pas bon au client et le socket se ferme. Si c est bon le serveur rajoute son nom a cette liste
4)Le client connecté envoit périodiquement une requete au serveur pour lui demander de reactualiser sa liste de connectés.
5)Le serveur renvoit au client cette liste.

Pour l'instant aucune partie envoie reception de message de tchat n'est gérée, mais tu verras bien que la liste d'affichage des clients est bien reactualisée a chaque fois qu 'un client se connecte/déconecte.

Code client (a partir du tien) :

import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;

import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;

import javax.swing.DefaultListModel;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JList;
import java.awt.Insets;
//////////
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;

////////

public class client extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JPanel jPanel = null;
	private JTextArea tenvoi = null;
	private JTextArea trecuArea = null;
	private JButton vButton = null;
	private JLabel jLabel1 = null;
	private JButton benvoyer = null;
	private JList lpseudo = null;    
////////Socket.......
	private Socket mClient = null;
	private String mNomClient;
	
/////////	

	
	private JPanel getJPanel() {
		if (jPanel == null) {
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 2;
			gridBagConstraints.gridy = 2;
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.fill = GridBagConstraints.BOTH;
			gridBagConstraints1.gridy = 0;
			gridBagConstraints1.weightx = 9.0;
			gridBagConstraints1.weighty = 1.0;
			gridBagConstraints1.gridwidth = 1;
			gridBagConstraints1.insets = new Insets(0, 0, 0, 0);
			gridBagConstraints1.ipadx = 0;
			gridBagConstraints1.gridx = 0;
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.fill = GridBagConstraints.BOTH;
			gridBagConstraints11.gridy = 0;
			gridBagConstraints11.weightx = 1.0;
			gridBagConstraints11.weighty = 1.0;
			gridBagConstraints11.ipadx = 0;
			gridBagConstraints11.ipady = 0;
			gridBagConstraints11.anchor = GridBagConstraints.WEST;
			gridBagConstraints11.gridwidth = 1;
			gridBagConstraints11.insets = new Insets(0, 1, 0, 0);
			gridBagConstraints11.gridx = 2;
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.gridx = 1;
			gridBagConstraints10.anchor = GridBagConstraints.NORTH;
			gridBagConstraints10.gridy = 2;
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.gridx = 1;
			gridBagConstraints9.gridy = 0;
			jLabel1 = new JLabel();
			jLabel1.setText("            ");
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints8.gridy = 2;
			gridBagConstraints8.weightx = 1.0;
			gridBagConstraints8.weighty = 0.0;
			gridBagConstraints8.gridwidth = 1;
			gridBagConstraints8.anchor = GridBagConstraints.NORTH;
			gridBagConstraints8.gridheight = 1;
			gridBagConstraints8.insets = new Insets(6, 4, 5, 0);
			gridBagConstraints8.gridx = 0;
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.gridx = 0;
			gridBagConstraints6.gridy = 1;
			//jLabel = new JLabel();
			//jLabel.setText("            ");
			jPanel = new JPanel();
			jPanel.setLayout(new GridBagLayout());
			//jPanel.add(jLabel, gridBagConstraints6);
			jPanel.add(getTenvoi(), gridBagConstraints8);
			jPanel.add(jLabel1, gridBagConstraints9);
			jPanel.add(getBenvoyer(), gridBagConstraints10);
			jPanel.add(getLpseudo(), gridBagConstraints11);
			jPanel.add(getTrecuArea(), gridBagConstraints1);
			jPanel.add(getVButton(), gridBagConstraints);
			
			

		}
			return jPanel;
	}
	
	private JTextArea getTenvoi() {
		if (tenvoi == null) {
			tenvoi = new JTextArea();
			//tenvoi.WIDTH=5.0;
		}
		return tenvoi;
	}

	private JButton getBenvoyer() {
		if (benvoyer == null) {
			benvoyer = new JButton();
			benvoyer.setText("Envoyer");
			benvoyer.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					
				}
			}); 
		}
		return benvoyer;
	}

	
	private JList getLpseudo() {
		if (lpseudo == null) {
			lpseudo = new JList();
		}
		return lpseudo;
	}

	
	
	private JTextArea getTrecuArea() {
		if (trecuArea == null) {
			trecuArea = new JTextArea();
			trecuArea.setEnabled(false);
		}  
		return trecuArea;
	}

	 
	private JButton getVButton() {
		if (vButton == null) {
			vButton = new JButton();
			vButton.setText("Tchatter");
			vButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					communicateWithServer();
				}
			});
		} 
		return vButton;    
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JFrame.setDefaultLookAndFeelDecorated(true);
		JDialog.setDefaultLookAndFeelDecorated(true);  
		/////////////////////////////////////
		
		////////////////////////////////////////////:
		
		SwingUtilities.invokeLater(new Runnable() { 
			public void run() {
				client thisClass = new client(); 
				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				thisClass.setVisible(true);
			}
		});
	}

	public client (){
		super();
		initialize();
		this.setBackground(Color.GREEN);
	}

	private void initialize() {
		this.setSize(648, 441);
		this.setContentPane(getJContentPane());
		this.setTitle("CLIENT");
		this.addWindowListener(new java.awt.event.WindowAdapter() { 
			
			public void windowClosing(java.awt.event.WindowEvent e) {      
				try {
						mClient.close(); 
					} catch (Exception ex) {
						System.out.println(ex.getMessage());
					}
			}                                                                    
			                                        
			public void windowOpened(java.awt.event.WindowEvent e) {
				if (mClient == null || mClient.isClosed()) {
					communicateWithServer();
				}
			}   
		});    
	}

	private JPanel getJContentPane() {         
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJPanel(), BorderLayout.CENTER);
		}
		return jContentPane;
	}
	
	private void communicateWithServer() {
		Thread vThread = new Thread() {
	           
            public void run () {
                try {
                	mClient = new Socket("localhost", 3500);
                    
                	if (authentificateWithServer(mClient)) {
                		while (true) {
                			displayClientsConnected(mClient);
                			
                			Thread.sleep(1000);
                		}
                	}
                	
                	mClient.close();
    			} catch (Exception e) {
                    e.printStackTrace(); 
                }               
            }
      
        };
        
        vThread.start();
	}
	
	public boolean authentificateWithServer(Socket pSocket) throws Exception {
		mNomClient = JOptionPane.showInputDialog(this , "Veuillez enter un nom pour tchatter :");
		
		if (mNomClient != null) {
			PrintWriter out= new PrintWriter(pSocket.getOutputStream(), true);
	        out.write(mNomClient + "\r\n");
	        out.flush();
	        
	        BufferedReader in=new BufferedReader(new InputStreamReader(pSocket.getInputStream()));
	        String vReponse = in.readLine();
	        
	        if (vReponse.startsWith("OK")) {
	        	return true;
	        } else {
	        	JOptionPane.showMessageDialog(this, "Ce nom existe deja !", "Warning", JOptionPane.WARNING_MESSAGE);
			}
		}
		
		return false;
	}
	
	public void displayClientsConnected(Socket pSocket) throws Exception {
		PrintWriter out= new PrintWriter(pSocket.getOutputStream(), true);
        out.write("DISPLAYCLIENTS\r\n");
        out.flush();
        
        BufferedReader in=new BufferedReader(new InputStreamReader(pSocket.getInputStream()));
        String req=new String();
        
        DefaultListModel dlm=new DefaultListModel();
        while(!(req=in.readLine()).startsWith("ENDCOMMAND")) {
        	System.out.println(req);
        	dlm.addElement(req);
        }
        
        lpseudo.setModel(dlm);
	}

}  //  @jve:decl-index=0:visual-constraint="10,10"

Code serveur (Refondu complètement) :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import java.util.HashMap;
//////////////////
public class serveur {
	
	private static String sEndCommand = "ENDCOMMAND\r\n";
	
	private HashMap<String, Object> mClients;

	public static void main(String[] args) {
		new serveur().launchServer();
	} 

	public void launchServer() {
		mClients = new HashMap<String, Object>();
		
		try {
			ServerSocket vServerSocket = new ServerSocket(3500);
		    while(true) {
		        final Socket vSocket = vServerSocket.accept();
		        
		        Thread vThread = new Thread() {
		           private String mCurrentThreadNomClient;
		        	
		           public void run() {
		        	   try {
		        		   mCurrentThreadNomClient = receiveAuthentificationFromClient(vSocket);
		        		   
		        		   while (!vSocket.isClosed()) {
		        			   sendListClientsConnectedToClient(vSocket);
		        		   }
		        		   
		        		   vSocket.close();
		        	   } catch (Exception e) {
		        		   mClients.remove(mCurrentThreadNomClient);
		        		   e.printStackTrace();
		        	   }
		           }
		           
		       };
		        
		       vThread.start();
		    }
		} catch (Exception e) { 
			e.printStackTrace();
		}
	}	
	
	private String receiveAuthentificationFromClient(Socket pSocket) throws Exception {
		BufferedReader vInputBufferedReader = new BufferedReader(new InputStreamReader(pSocket.getInputStream()));
        String vNomClient = vInputBufferedReader.readLine();
        
        PrintWriter out= new PrintWriter(pSocket.getOutputStream(), true);
                
        if (mClients.containsKey(vNomClient)) {
        	out.write("KO\r\n");
            out.flush();
            pSocket.close();
            return null;
        } else {
        	mClients.put(vNomClient, null);
        	out.write("OK\r\n");
            out.flush();
        }
        
        return vNomClient;
	}
	
	private void sendListClientsConnectedToClient(Socket pSocket) throws Exception {
		BufferedReader vInputBufferedReader = new BufferedReader(new InputStreamReader(pSocket.getInputStream()));
		String vRequest = vInputBufferedReader.readLine();
				
		if (vRequest.startsWith("DISPLAYCLIENTS")) {
			PrintWriter out= new PrintWriter(pSocket.getOutputStream(), true);
	        
			for (String vClientNomTmp : mClients.keySet()) {
				out.write(vClientNomTmp + "\r\n");
			}
			
			out.write(sEndCommand);
			out.flush();
		}		
	}
	
}  //  @jve:decl-index=0:visual-constraint="10,10"

Je te laisse regarder ce code, si tu as tt compris tu me dis et on passera à l étape deux : l'envoi reception de données de tchat.

Bonne chance,
Niroken

taoufik109

slt, merci pour le code, tout est clair, c ke j'ai pa bien compris c le HashMap et son fonctionnement.

j'ai executé le code sur la meme machine le client et le serveur, ca marche tres bien, je lance plusieurs clients sur meme machine et ca marche osi.

j'ai executé le code sur deux machines, serveur sur l'un et client sur l'autre mé ca marche pa (je change l'ip du socket client avec l'ip du serveur) :D

voici l'erreur au niveau client:

java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.(Unknown Source)
at java.net.Socket.(Unknown Source)
at client$5.run(client.java:221)
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.(Unknown Source)
at java.net.Socket.(Unknown Source)
at client$5.run(client.java:221)
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.(Unknown Source)
at java.net.Socket.(Unknown Source)
at client$5.run(client.java:221)
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.(Unknown Source)
at java.net.Socket.(Unknown Source)
at client$5.run(client.java:221)
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.(Unknown Source)
at java.net.Socket.(Unknown Source)
at client$5.run(client.java:221)

si vous arrivez a resoudre ce petit probleme, vous pouvez me communiquer avec, le code d'envoi et reception de message(chat), et merci infiniment :D

Niroken

Hmmm

J'ai de mon coté fait le test suivant :

- Serveur sur un poste et client sur le même poste.
- Client sur un autre poste

Je n'ai eu aucun soucis.

Cependant, ton erreur "Connection timed out" me ferait davantage penser, à un firewall qui bloque l échange de données sur le réseau.

--------------------------------------------------------------------------------

Ensuite il est vrai que mettre les infos de connexions en dur dans le code, c'est moyen donc je te passe ceci :

C'est une classe utilitaire crée par moi :) qui permet de lire les fichiers de configuration (.properties) en java



import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class ConfigReader {
    
    private Properties mProperties;
    private static ConfigReader sInstance;
        
    private ConfigReader(String pFilePropertiesName) throws IOException {
        readConfig(pFilePropertiesName);
    }
    
    public static ConfigReader getInstance(String pFilePropertiesName) {
        if (sInstance == null) {
            try {
                sInstance = new  ConfigReader(pFilePropertiesName);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("Impossible de lire le fichier " + pFilePropertiesName);
            }
        }
        
        return sInstance;
    }
        
    private void readConfig(String pFilePropertiesName) throws IOException {
        mProperties = new Properties();
        FileInputStream vFileInputStream = new FileInputStream(pFilePropertiesName);
        mProperties.load(vFileInputStream);
        vFileInputStream.close();
    }

    public String getProperty(String pKey) {
        return mProperties.getProperty(pKey);
    }
    
    public Properties getProperties() {
        return mProperties;
    }
    
    public static String getClasspathResource(String pResourcePath) {
        String vPath = pResourcePath;
        
        if (vPath.startsWith("/")) {
            vPath = vPath.substring(1);
        }
        
        try {
            return Thread.currentThread().getContextClassLoader().getResource(vPath).getPath().replaceAll("%20", " ");
        } catch (Exception pException) {
            throw new RuntimeException("La ressource " + pResourcePath + " n est pas dans le classpath !");
        }
    }
    
}

Je te met ici la méthode à modifier coté client :

private void communicateWithServer() {
		Thread vThread = new Thread() {
	           
            public void run () {
                try {
                	int vPortServeur = Integer.parseInt(ConfigReader.getInstance("client.properties").getProperty("serveur.port"));
                	String vIpServeur = ConfigReader.getInstance("client.properties").getProperty("serveur.ip");
                	mClient = new Socket(vIpServeur, vPortServeur);
                    
                	if (authentificateWithServer(mClient)) {
                		while (true) {
                			displayClientsConnected(mClient);
                			
                			Thread.sleep(1000);
                		}
                	}
                	
                	mClient.close();
    			} catch (Exception e) {
                    e.printStackTrace(); 
                }               
            }
      
        };
        
        vThread.start();
	}

La méthode à modifier coté serveur :

public void launchServer() {
		mClients = new HashMap<String, Object>();
		
		try {
			int vPortServeur = Integer.parseInt(ConfigReader.getInstance("serveur.properties").getProperty("serveur.port"));
			ServerSocket vServerSocket = new ServerSocket(vPortServeur);
		    while(true) {
		        final Socket vSocket = vServerSocket.accept();
		        
		        Thread vThread = new Thread() {
		           private String mCurrentThreadNomClient;
		        	
		           public void run() {
		        	   try {
		        		   mCurrentThreadNomClient = receiveAuthentificationFromClient(vSocket);
		        		   
		        		   while (!vSocket.isClosed()) {
		        			   sendListClientsConnectedToClient(vSocket);
		        		   }
		        		   
		        		   vSocket.close();
		        	   } catch (Exception e) {
		        		   mClients.remove(mCurrentThreadNomClient);
		        		   e.printStackTrace();
		        	   }
		           }
		           
		       };
		        
		       vThread.start();
		    }
		} catch (Exception e) { 
			e.printStackTrace();
		}
	}	

Tu dois donc éditer un fichier de config pour le serveur que tu mettras dans le répertoire ou s executes ton serveur "serveur.properties"

serveur.port=3500

De même pour le fichier de config client "client.properties"

serveur.port=3500
serveur.ip=localhost

C'est plus propre comme ca tu peux modifier la config, sans changer le code.

Pour en finir je vais répondre à ta dernière question : la HashMap

En fait il s'agit d'une structure de données indéxée : ici c'est par nom de client.

Structure de données, oui, mais quelle données??, ici cette HashMap va contenir la liste des messages en attente pour chaque client.

J'avais préparé le terrain pour l'étape 2 :

- Toutes les 1s le client envoit une requete au serveur, dans cette requete on va également envoyer ce que le client a saisi.
- Le serveur va recevoir cette requete et va ajouter le ou les messages du client aux listes de messages en attente de tous les autres clients.
- Puis le serveur renvoit au client sa liste des messages en attente.

La dans le scénario que je viens de décrire, a chaque fois qu un client ecrira un message, il sera vu par tous les autres clients.
Mais si tu veux ecrire un "private message" visible que par un seul client, le serveur ajoutera le message du client seuelement au client destinataire concerné.

L'interet de la HashMap c'est que comme c'est indéxée par nom de client, si tu veux atteindre la liste des messages dun client donné : tu fais :

vHashMap.get("nomDeClient");

Où vHashMap est une instance de HashMap.

Je te passe la partie pour le tchat dem1, faut quand même le temp de la coder :)

Bonne chance,
Niroken

Niroken

Hello,

Voici le petit Tchat client/serveur bien avancé avec la gestion des envois/réception de messages.

Il y a évidemment moyen d'optimiser ca : la je n'ai mis qu'une gestion très légère des exceptions et le code est un peu mélangé, on aurait pu factoriser ca un peu mieux, ceci dit, ca marche...je te tansmets donc le code complet :

Code client :

import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;

import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;

import javax.swing.DefaultListModel;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JList;

import java.awt.Insets;
//////////
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.*;
import java.util.ArrayList;
import java.util.List;

////////

public class client extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JPanel jPanel = null;
	private JTextArea tenvoi = null;
	private JTextArea trecuArea = null;
	private JButton vButton = null;
	private JLabel jLabel1 = null;
	private JButton benvoyer = null;
	private JList lpseudo = null;    
////////Socket.......
	private Socket mClientSocket = null;
	private String mClientNom;
	private List<ClientMessage> mClientsMessages;
	
/////////	

	
	private JPanel getJPanel() {
		if (jPanel == null) {
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 2;
			gridBagConstraints.gridy = 2;
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.fill = GridBagConstraints.BOTH;
			gridBagConstraints1.gridy = 0;
			gridBagConstraints1.weightx = 9.0;
			gridBagConstraints1.weighty = 1.0;
			gridBagConstraints1.gridwidth = 1;
			gridBagConstraints1.insets = new Insets(0, 0, 0, 0);
			gridBagConstraints1.ipadx = 0;
			gridBagConstraints1.gridx = 0;
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.fill = GridBagConstraints.BOTH;
			gridBagConstraints11.gridy = 0;
			gridBagConstraints11.weightx = 1.0;
			gridBagConstraints11.weighty = 1.0;
			gridBagConstraints11.ipadx = 0;
			gridBagConstraints11.ipady = 0;
			gridBagConstraints11.anchor = GridBagConstraints.WEST;
			gridBagConstraints11.gridwidth = 1;
			gridBagConstraints11.insets = new Insets(0, 1, 0, 0);
			gridBagConstraints11.gridx = 2;
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.gridx = 1;
			gridBagConstraints10.anchor = GridBagConstraints.NORTH;
			gridBagConstraints10.gridy = 2;
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.gridx = 1;
			gridBagConstraints9.gridy = 0;
			jLabel1 = new JLabel();
			jLabel1.setText("            ");
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints8.gridy = 2;
			gridBagConstraints8.weightx = 1.0;
			gridBagConstraints8.weighty = 0.0;
			gridBagConstraints8.gridwidth = 1;
			gridBagConstraints8.anchor = GridBagConstraints.NORTH;
			gridBagConstraints8.gridheight = 1;
			gridBagConstraints8.insets = new Insets(6, 4, 5, 0);
			gridBagConstraints8.gridx = 0;
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.gridx = 0;
			gridBagConstraints6.gridy = 1;
			//jLabel = new JLabel();
			//jLabel.setText("            ");
			jPanel = new JPanel();
			jPanel.setLayout(new GridBagLayout());
			//jPanel.add(jLabel, gridBagConstraints6);
			jPanel.add(getTenvoi(), gridBagConstraints8);
			jPanel.add(jLabel1, gridBagConstraints9);
			jPanel.add(getBenvoyer(), gridBagConstraints10);
			jPanel.add(getLpseudo(), gridBagConstraints11);
			jPanel.add(getTrecuArea(), gridBagConstraints1);
			jPanel.add(getVButton(), gridBagConstraints);
			
			

		}
			return jPanel;
	}
	
	private JTextArea getTenvoi() {
		if (tenvoi == null) {
			tenvoi = new JTextArea();
			//tenvoi.WIDTH=5.0;
		}
		return tenvoi;
	}

	private JButton getBenvoyer() {
		if (benvoyer == null) {
			benvoyer = new JButton();
			benvoyer.setText("Envoyer");
			benvoyer.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					ClientMessage vClientMessage = new ClientMessage();
					vClientMessage.setClientNom(mClientNom);
					vClientMessage.setMessage(tenvoi.getText());
					
					trecuArea.append(vClientMessage.getClientNom() + " : ");
					trecuArea.append(vClientMessage.getMessage());
					trecuArea.append(System.getProperty("line.separator"));
					trecuArea.append(System.getProperty("line.separator"));
					
					mClientsMessages.add(vClientMessage);
				}
			}); 
		}
		return benvoyer;
	}

	
	private JList getLpseudo() {
		if (lpseudo == null) {
			lpseudo = new JList();
		}
		return lpseudo;
	}

	
	
	private JTextArea getTrecuArea() {
		if (trecuArea == null) {
			trecuArea = new JTextArea();
			trecuArea.setEnabled(false);
		}  
		return trecuArea;
	}

	 
	private JButton getVButton() {
		if (vButton == null) {
			vButton = new JButton();
			vButton.setText("Tchatter");
			vButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if (mClientSocket == null || mClientSocket.isClosed()) {
						communicateWithServer();
					}
				}
			});
		} 
		return vButton;    
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JFrame.setDefaultLookAndFeelDecorated(true);
		JDialog.setDefaultLookAndFeelDecorated(true);  
		/////////////////////////////////////
		
		////////////////////////////////////////////:
		
		SwingUtilities.invokeLater(new Runnable() { 
			public void run() {
				client thisClass = new client(); 
				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				thisClass.setVisible(true);
			}
		});
	}

	public client (){
		super();
		initialize();
		this.setBackground(Color.GREEN);
	}

	private void initialize() {
		this.setSize(648, 441);
		this.setContentPane(getJContentPane());
		this.setTitle("CLIENT");
		this.mClientsMessages = new ArrayList<ClientMessage>();
		this.addWindowListener(new java.awt.event.WindowAdapter() { 
			
			public void windowClosing(java.awt.event.WindowEvent e) {      
				try {
						mClientSocket.close(); 
					} catch (Exception ex) {
						System.out.println(ex.getMessage());
					}
			}                                                                    
			                                        
			public void windowOpened(java.awt.event.WindowEvent e) {
				if (mClientSocket == null || mClientSocket.isClosed()) {
					communicateWithServer();
				}
			}   
		});    
	}

	private JPanel getJContentPane() {         
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJPanel(), BorderLayout.CENTER);
		}
		return jContentPane;
	}
	
	private void communicateWithServer() {
		Thread vThread = new Thread() {
	           
            public void run () {
                try {
                	int vPortServeur = Integer.parseInt(ConfigReader.getInstance("client.properties").getProperty("serveur.port"));
                	String vIpServeur = ConfigReader.getInstance("client.properties").getProperty("serveur.ip");
                	mClientSocket = new Socket(vIpServeur, vPortServeur);
                    
                	if (authentificateWithServer(mClientSocket)) {
                		while (true) {
                			displayClientsConnected(mClientSocket);
                			sendMessagesToServer(mClientSocket);
                			receiveMessagesFromServer(mClientSocket);
                			
                			Thread.sleep(1000);
                		}
                	}
                	
                	mClientSocket.close();
    			} catch (Exception e) {
                    e.printStackTrace(); 
                }               
            }
      
        };
        
        vThread.start();
	}
	
	private boolean authentificateWithServer(Socket pSocket) throws Exception {
		mClientNom = JOptionPane.showInputDialog(this , "Veuillez enter un nom pour tchatter :");
		
		if (mClientNom != null) {
			PrintWriter out= new PrintWriter(pSocket.getOutputStream(), true);
	        out.write(mClientNom + "\r\n");
	        out.flush();
	        
	        BufferedReader in=new BufferedReader(new InputStreamReader(pSocket.getInputStream()));
	        String vReponse = in.readLine();
	        
	        if (vReponse.startsWith("OK")) {
	        	return true;
	        } else {
	        	JOptionPane.showMessageDialog(this, "Ce nom existe deja !", "Warning", JOptionPane.WARNING_MESSAGE);
			}
		}
		
		return false;
	}
	
	private void displayClientsConnected(Socket pSocket) throws Exception {
		PrintWriter out= new PrintWriter(pSocket.getOutputStream(), true);
        out.write("DISPLAYCLIENTS\r\n");
        out.flush();
        
        BufferedReader in=new BufferedReader(new InputStreamReader(pSocket.getInputStream()));
        String req=new String();
        
        DefaultListModel dlm=new DefaultListModel();
        while(!(req=in.readLine()).startsWith("ENDCOMMAND")) {
        	dlm.addElement(req);
        }
        
        lpseudo.setModel(dlm);
	}
	
	private void sendMessagesToServer(Socket pSocket) throws Exception {
		ObjectOutputStream vObjectOutputStream = new ObjectOutputStream(pSocket.getOutputStream());
		vObjectOutputStream.writeObject(mClientsMessages);
		vObjectOutputStream.flush();
		
		mClientsMessages.clear();
	}
	
	private void receiveMessagesFromServer(Socket pSocket) throws Exception {
		ObjectInputStream vObjectInputStream = new ObjectInputStream(pSocket.getInputStream());
		List<ClientMessage> vClientsReceivedMessages = (List<ClientMessage>) vObjectInputStream.readObject();
		
		for (ClientMessage vClientMessageReceivedTmp : vClientsReceivedMessages) {
			trecuArea.append(vClientMessageReceivedTmp.getClientNom() + " : ");
			trecuArea.append(vClientMessageReceivedTmp.getMessage());
			trecuArea.append(System.getProperty("line.separator"));
			trecuArea.append(System.getProperty("line.separator"));
		}
	}

}  //  @jve:decl-index=0:visual-constraint="10,10"

Code serveur :

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
//////////////////
public class serveur {
	
	private static String sEndCommand = "ENDCOMMAND\r\n";
	
	private HashMap<String, List<ClientMessage>> mClientsMessages;

	public static void main(String[] args) {
		new serveur().launchServer();
	} 

	public void launchServer() {
		mClientsMessages = new HashMap<String, List<ClientMessage>>();
		
		try {
			int vPortServeur = Integer.parseInt(ConfigReader.getInstance("serveur.properties").getProperty("serveur.port"));
			ServerSocket vServerSocket = new ServerSocket(vPortServeur);
		    while(true) {
		        final Socket vSocket = vServerSocket.accept();
		        
		        Thread vThread = new Thread() {
		           private String mCurrentThreadNomClient;
		        	
		           public void run() {
		        	   try {
		        		   mCurrentThreadNomClient = receiveAuthentificationFromClient(vSocket);
		        		   
		        		   while (!vSocket.isClosed()) {
		        			   sendListClientsConnectedToClient(vSocket);
		        			   receiveMessagesFromClient(vSocket, mCurrentThreadNomClient);
		        			   sendMessagesToClient(vSocket, mCurrentThreadNomClient);
		        		   }
		        		   
		        		   vSocket.close();
		        	   } catch (Exception e) {
		        		   mClientsMessages.remove(mCurrentThreadNomClient);
		        		   e.printStackTrace();
		        	   }
		           }
		           
		       };
		        
		       vThread.start();
		    }
		} catch (Exception e) { 
			e.printStackTrace();
		}
	}	
	
	private String receiveAuthentificationFromClient(Socket pSocket) throws Exception {
		BufferedReader vInputBufferedReader = new BufferedReader(new InputStreamReader(pSocket.getInputStream()));
        String vNomClient = vInputBufferedReader.readLine();
        
        PrintWriter out= new PrintWriter(pSocket.getOutputStream(), true);
                
        if (mClientsMessages.containsKey(vNomClient)) {
        	out.write("KO\r\n");
            out.flush();
            pSocket.close();
            return null;
        } else {
        	mClientsMessages.put(vNomClient, new ArrayList<ClientMessage>());
        	out.write("OK\r\n");
            out.flush();
        }
        
        return vNomClient;
	}
	
	private void sendListClientsConnectedToClient(Socket pSocket) throws Exception {
		BufferedReader vInputBufferedReader = new BufferedReader(new InputStreamReader(pSocket.getInputStream()));
		String vRequest = vInputBufferedReader.readLine();
				
		if (vRequest.startsWith("DISPLAYCLIENTS")) {
			PrintWriter out= new PrintWriter(pSocket.getOutputStream(), true);
	        
			for (String vClientNomTmp : mClientsMessages.keySet()) {
				out.write(vClientNomTmp + "\r\n");
			}
			
			out.write(sEndCommand);
			out.flush();
		}
	}
	
	private void sendMessagesToClient(Socket pSocket, String pCurrentClient) throws Exception {
		ObjectOutputStream vObjectOutputStream = new ObjectOutputStream(pSocket.getOutputStream());
		vObjectOutputStream.writeObject(mClientsMessages.get(pCurrentClient));
		vObjectOutputStream.flush();
		
		mClientsMessages.get(pCurrentClient).clear();
	}
	
	private void receiveMessagesFromClient(Socket pSocket, String pCurrentClient) throws Exception {
		ObjectInputStream vObjectInputStream = new ObjectInputStream(pSocket.getInputStream());
		List<ClientMessage> vClientsReceivedMessages = (List<ClientMessage>) vObjectInputStream.readObject();
		
		for (String vClientNom : mClientsMessages.keySet()) {
			if (!vClientNom.equals(pCurrentClient)) {
				mClientsMessages.get(vClientNom).addAll(vClientsReceivedMessages);
			}
		}
	}
	
}  //  @jve:decl-index=0:visual-constraint="10,10"

ConfigReader :



import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class ConfigReader {
    
    private Properties mProperties;
    private static ConfigReader sInstance;
        
    private ConfigReader(String pFilePropertiesName) throws IOException {
        readConfig(pFilePropertiesName);
    }
    
    public static ConfigReader getInstance(String pFilePropertiesName) {
        if (sInstance == null) {
            try {
                sInstance = new  ConfigReader(pFilePropertiesName);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("Impossible de lire le fichier " + pFilePropertiesName);
            }
        }
        
        return sInstance;
    }
        
    private void readConfig(String pFilePropertiesName) throws IOException {
        mProperties = new Properties();
        FileInputStream vFileInputStream = new FileInputStream(pFilePropertiesName);
        mProperties.load(vFileInputStream);
        vFileInputStream.close();
    }

    public String getProperty(String pKey) {
        return mProperties.getProperty(pKey);
    }
    
    public Properties getProperties() {
        return mProperties;
    }
    
    public static String getClasspathResource(String pResourcePath) {
        String vPath = pResourcePath;
        
        if (vPath.startsWith("/")) {
            vPath = vPath.substring(1);
        }
        
        try {
            return Thread.currentThread().getContextClassLoader().getResource(vPath).getPath().replaceAll("%20", " ");
        } catch (Exception pException) {
            throw new RuntimeException("La ressource " + pResourcePath + " n est pas dans le classpath !");
        }
    }
    
}

ClientMessage :



import java.io.Serializable;

public class ClientMessage implements Serializable {
	
	private static final long serialVersionUID = 1L;
	
	private String mMessage;
	private String mClientNom;
	
	public String getMessage() {
		return mMessage;
	}
	
	public void setMessage(String pMessage) {
		mMessage = pMessage;
	}
	
	public String getClientNom() {
		return mClientNom;
	}
	
	public void setClientNom(String pClientNom) {
		mClientNom = pClientNom;
	}	
	
}

Ce tchatter est fonctionnel, ceci dit, je n'ai pas géré l'envoi de messages privés :) , ca fera un bon exercice pour toi :)

Bonne chance,
Niroken

taoufik109

Merci pour le code ca marche parfaitement.

j'ai essayé d'ajouter des jscrollpane au zone de text d'envoi et de reception, avec le code ke tu m'as donnée l'autre fois mé ca marche pa:

setSize(300, 300);
      setLayout(new FlowLayout());
      
      trecuArea = new JTextArea();
      
      JScrollPane vScrollPane = new JScrollPane(trecuArea);
      vScrollPane.setPreferredSize(new Dimension(100, 100));

      add(vScrollPane);
      
      setVisible(true);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

osi j'ai essayé de faire les messages privés mé vu ke ton code est un petit peu long, j'ai pa réussit à le faire.

Merci de me résoudre ces deux problemes ki restent.

osi j'ai besoin de ton nom pour le mentionner dans le rapport. :D

Niroken

Lol jvais avoir une bonne note dis donc.
Bah écoute, jte ferais ca, d ici dem1, après-dem1.

Niroken

taoufik109

Merci bcp, bien sur ke tu aura une bonne note :D

taoufik109

salut, est ce ke ca va ?
est ce ke t'as rencontré des problemes pour les deux trucs, j'éspere ke ca marche pour toi

Niroken

Hello,

Si je n'ai pas encore donné suite, c'est plus par manque de temp en fait, mais je vais m'y atteller ce soir, j'espère avoir fini donc.

Niroken

taoufik109

ok, merci, j'espére ke tu finira aujourdhui, aufwiedersehen :D

taoufik109

slt, ca va bien Niroken ?
je crois que tu m'as oublié, voila mon msn: eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%74%61%6f%75%66%69%6b%31%30%39%40%68%6f%74%6d%61%69%6c%2e%63%6f%6d%22%3e%74%61%6f%75%66%69%6b%31%30%39%40%68%6f%74%6d%61%69%6c%2e%63%6f%6d%3c%2f%61%3e%27%29%3b')),
juste pour communiquer plus vite, merci.