IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

Socket et Threads


Sujet :

Entrée/Sortie Java

  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 91
    Par défaut Socket et Threads
    Bonjour à tous.

    Je suis actuellement en train de découvrir l'utilisation de socket en Java, et j'ai un petit probleme.

    Voici les différentes parties de mon code :
    Client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    import java.io.BufferedInputStream;
    import java.io.BufferedReader;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.Inet4Address;
    import java.net.Socket;
    import java.net.UnknownHostException;
     
     
    public class Client {
    	Socket sock;
    	String ipAddress;
     
     
    	public Client(){
    		ipAddress = "127.0.0.1";
    		int port = 4242;
     
    		try {
    			System.out.println("Trying to connect on port :"+port +"a l'adresse ip :"+ipAddress);
    			sock = new Socket(ipAddress, port);
    			System.out.println("Connecté");
    			DataInputStream dIS = new DataInputStream(sock.getInputStream());
    			DataOutputStream dOS = new DataOutputStream(sock.getOutputStream());
    			while(true)
    			{
    				InputStreamReader is = new InputStreamReader(System.in);
    				BufferedReader bR = new BufferedReader(is);
    				String str = bR.readLine();
    				byte[] b = new byte[256];
    				b = str.getBytes();
    				if(str!=null){
    					dOS.write(b);
    					System.out.println("Message envoyé");
    				}
     
    			}
     
    		} catch (UnknownHostException e) {
    			System.out.println("The host has not been found");
    		} catch (IOException e) {
    			System.out.println("IO error");
    			e.printStackTrace();
    		}
     
    	}
     
     
     
     
    }
    Serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Vector;
     
     
    public class MasterServer {
    	Vector<Thread> serverThreadVector;
    	ServerSocket servSock ;
    	boolean state = true;
    	int nbConnection = 0;
    	String sharedString;
     
    	public MasterServer(){
    		serverThreadVector = new Vector<Thread>();
    		try {
    			if(servSock==null){
    				servSock = new ServerSocket(4242);
    			}
    			while(state){
    				System.out.println("blabla");
    				Socket client = servSock.accept();
    				System.out.println("blabla");
    				nbConnection++;
    				Runnable sRunnable = new ServerThread(client, sharedString);
    				Thread sThread = new Thread(sRunnable);
    				serverThreadVector.add(sThread);
    				sThread.run();
     
    			}
    		} catch (IOException e) {
    			System.out.println("IO exceptions not handled");
    			e.printStackTrace();
    		} catch (Exception e){
    			String msg = e.getMessage();
    			for (Thread thr : serverThreadVector) {
    				sharedString = msg;
    				thr.interrupt();
    			}
    		}
    	}
     
     
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    import java.io.BufferedReader;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.Socket;
     
     
    public class ServerThread implements Runnable {
    	Socket clientSocket ;
    	String sString;
    	String oldSString;
    	String servString;
    	DataInputStream dIS;
    	BufferedReader bR;
    	DataOutputStream dOS;
    	boolean state;
     
     
    	public void setSString(String s){
    		sString = s;
    	}
     
    	public ServerThread(Socket client, String sharedString) {
    		clientSocket = client;
    		servString = sharedString;
    		oldSString = "";
    		state = true;
    		try {
    			dIS = new DataInputStream(client.getInputStream());
    			bR = new BufferedReader(new InputStreamReader(dIS));
    			dOS = new DataOutputStream(client.getOutputStream());
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
     
    	}
     
     
     
    	public void run() {
    		while(state){
    			try {
    				Thread.sleep(10);
    				while(true){
    					byte[] b = new byte[256];
    					dIS.read(b);
    					String str = new String(b);
    					System.out.println(str);
    				}
    			} catch (Exception e) {
    				try {
    					byte[] b = servString.getBytes();
    					dOS.write(b);
    				} catch (IOException e1) {
    					System.out.println("Message non envoyé");
    					e1.printStackTrace();
    				}
    			}
    		}
    	}
     
    }
    En lancant avec un seul client, j'arrive bien a ce que je veux, c'est a dire envoi/reception de message du client vers le serveur.
    Lorsque je lance un second client, le comportement souhaité serait d'accepter la connexion sur un nouveau socket, de lancer un thread pour ce socket, et d'ajouter ce thread a un vecteur de thread.

    Apparemment le second client crée bien son socket de communication, mais le serveur de rerentre jamais dans sa boucle d'attente de nouvelle connexion, donc je ne peux envoyer de message de mon second client.

    Une idée de la ou je me serais planté en beauté ?

    Merci d'avance

  2. #2
    Membre actif
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2011
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2011
    Messages : 65
    Par défaut Peut-être une piste
    Salut!

    J'observe ton code attentivement et quelque chose me gêne dans ton code du thead ServerThread, plus précisément dans la méthode run()...
    En effet, tu le fait dormir quelques 10 secondes, puis tu envoies sur un while(true). Selon moi ton sleep(10) devrait être dans ta boucle while non?

    Enfin je n'en suis pas sûr mais si ça peut être ça je te l'écris

    Et attention, 10 ms ça me paraît court pour du java ^^

    @+

  3. #3
    Membre émérite
    Avatar de bpy1401
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2003
    Messages
    511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2003
    Messages : 511
    Par défaut
    Bonjour Rastafire

    Coté serveur line 29

    remplace cette ligne par

    Cordialement
    Page sur Developpez : http://pbriand.developpez.com

  4. #4
    Membre actif
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2011
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2011
    Messages : 65
    Par défaut
    C'est pas faux, mais c'est pas moi qui ait posté à l'origine ^^, en tout cas bien vu

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 15
    Par défaut
    bonjour ,

    essaie de faire appelle a ton thread

    tonthread.start();

  6. #6
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 91
    Par défaut
    Effectivement, c'était ca qui plantait mon programme !
    Erreur bête, souvent les plus dures a repérer :'(

    Concernant le sleep, effectivement il est mal placé. Je découvre un peu l'implémentation des threads, mais je me demande même si a l'intérieur du while il n'est pas inutile.

    Quelqu'un aurait une idée de ce qu'il apporte réellement, ou de ce qu'il empeche ? Je ne l'ai mis que parcequ'un de mes profs (ou site de référence je ne sais plus) l'avait utilisé en précisant que c'était important, mais je n'ai pas la raison en tête.

    Merci a vous néanmoins pour mon premier probleme.

    Edit : Je rajoute une petite question. Si le nombre maximal de port disponible est utilisé, que se passe-t-il ? Y'a-t-il un overlap des sockets sur des ports déja existants ? Une exception est levée ? Comment gérer ce probleme proprement ? Merci d'avance si vous répondez a ces questions.

  7. #7
    Membre actif
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2011
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2011
    Messages : 65
    Par défaut Utilité de sleep()
    Le sleep permet de ne pas accaparer tes ressources pendant toute la durée du while(true), donc indéfiniment, c'est pour cela qu'à mon sens 10ms ça semble pareil que si tu n'en mettais pas, à peu de choses près.

    Normalement si tu n'as plus aucune connexion disponible, tu devrais avoir une SocketException("Le nombre maximal de connexions a été atteint"), ou un message approchant je ne me rappelle plus bien.
    Des bonnes solutions il y en a plusieurs.

    La plus simple: un catch (SocketException e) avec un renvoi de booléen pour le client lui indiquant qu'il n'est toujours pas connecté, et dans la partie cliente tu renvoie tant que la connexion n'a pas été établie.

    Il y en a des plus complexes, mais là de tête, et n'étant pas un grand spécialiste du réseau, je ne m'aventurerai pas à émettre es hypothèses vaseuses

    Voilà j'espère que ça t'apporte quelques réponses

  8. #8
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 91
    Par défaut
    Merci pour ces réponses, je passe le sujet en résolu.

    Concernant le nombre de port, effectivement, j'avais déja pensé a lever une exception empechant le client de se connecter, mais je me demandais plus si il y avait une solution pour connecter plus de client que le nombre de port disponible (un truc un peu "hors norme"), par exemple dans mon cas pour un chat.

    Bien entendu je ne m'attend pas a voir 65k (il me semble) personne se connecter sur le même serveur, mais si une solution existe, encore une fois en êtant un peu hors norme, elle permettrait peut etre de connecter un nombre réduit n de machine sur un nombre de port < n.

    Merci néanmoins pour ta réponse,

    Al_th

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Socket et thread
    Par mayu5 dans le forum Réseau
    Réponses: 6
    Dernier message: 13/05/2008, 00h56
  2. problème socket et thread
    Par dc.sara dans le forum C
    Réponses: 2
    Dernier message: 12/03/2008, 07h58
  3. Programmation réseau : socket et thread
    Par roms712 dans le forum POSIX
    Réponses: 12
    Dernier message: 12/01/2007, 17h27
  4. Sockets TCP/ Threads
    Par guillaume16 dans le forum C++
    Réponses: 3
    Dernier message: 27/07/2006, 23h45
  5. Sockets et threads...
    Par Kiff dans le forum Réseau/Web
    Réponses: 6
    Dernier message: 27/07/2004, 17h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo