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

avec Java Discussion :

Thread et réception UDP


Sujet :

avec Java

  1. #1
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Thread et réception UDP
    Bonjour,
    Je suis débutant en Java et j'essaye de faire communiquer mon MAC avec un ARDRONE . Avant de mettre en péril le drone je fais mes essais entre deux Mac pour voir si la communication fonctionne et pour la réception ça fait 15 jours que je cherche et que je ne trouve pas ma solution . Je joins la classe ReceiverThread ou il n'y a malheureusement aucune réception et ma Classe Main.

    Est ce que cette absence de réception est lié au fait que la méthode receive() soit "bloquante" ? ou bien est un problème de conception de Thread?
    Pouvez vous m'éclairer sans entrer dans un vocabulaire informatique trop évolué ce n'est pas ma profession , je suis autodidacte et surtout simple passionné.
    En vous remerciant d'avance.

    Mon Main()

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    import java.net.InetAddress;
    import java.util.StringTokenizer;
     
    public class MainClass {
     
      public static void main(String[] args) throws Exception {
     
    	  CommandeAT [] Item;
    		Item = new CommandeAT[11];
    		Item[0] = new CommandeAT ("Decollage","AT*REF=",100,290718208);// Faire une incremenatation des N° de sequence et ... recup etat de la batterie
    		Item[1] = new CommandeAT ("Atterrissage","AT*REF=",100,290717696);
    		Item[2] = new CommandeAT ("Stationnaire","AT*PCMD=",100,1,0,0,0,0);
    		Item[3] = new CommandeAT ("plusdegaz","AT*PCMD=",100,1,0,0,1036831949,0);
    		Item[4] = new CommandeAT ("moinsdegaz","AT*PCMD=",100,1,0,0,-1110651699,0);
    		Item[5] = new CommandeAT ("plusdeTangage","AT*PCMD=",100,1,1036831949,0,0,0);
    		Item[6] = new CommandeAT ("moinsdeTangage","AT*PCMD=",100,1,-1110651699,0,0,0);
    		Item[7] = new CommandeAT ("plusMvtLacet","AT*PCMD=",100,1,0,0,0,1036831949);
    		Item[8] = new CommandeAT ("moinsMvtLacet","AT*PCMD=",100,1,0,0,0,-1110651699);
    		Item[9] = new CommandeAT ("plusderoulis","AT*PCMD=",100,1,0,1036831949,0,0);
    		Item[10] = new CommandeAT ("Init","AT*CONFIG=1,\"control:altitude_max\",\"2000\"");
    		Instruction AT = new Instruction("","");
    		int sequence=0;
    		int ordre[] = {10,0,2,1};
        String ip = "192.168.0.16";
        //////////////////////////////////////////////////////////////////////////////
        				//		Codage adresse    //
        ////////////////////////////////////////////////////////////////////////////
        StringTokenizer st = new StringTokenizer(ip, ".");
        byte[] ip_bytes = new byte[4];// on traduit l'adresse ensuite en 4 octets
    	if (st.countTokens() == 4)
    	{
     	    for (int i = 0; i < 4; i++)
     	    {
    		ip_bytes[i] = (byte)Integer.parseInt(st.nextToken());
    	    }
    	}
    	InetAddress ia = InetAddress.getByAddress(ip_bytes); 
    	System.out.println("Inet "+ia);
    //////////////////////////////////////////////////////////////////////////////
    	//                  Envoie de la sequence et de la reception		//
    //////////////////////////////////////////////////////////////////////////////	
    	 for (int j=0 ;j< ordre.length; j++)
    		{	
    			if (Item[ordre[j]].Codage=="AT*REF=") {AT = somme (Item[ordre[j]],sequence);} else 
    			if (Item[ordre[j]].Codage=="AT*CONFIG=1,\"control:altitude_max\",\"2000\"") {AT = somme2 (Item[10]);} else// voir instruction a envoyer;
    			if (Item[ordre[j]].Codage=="AT*PCMD="){AT = somme1 (Item[ordre[j]],sequence);}
    			String a = AT.CodageI;
     
         	byte[] buf = (a + "\r").getBytes();
     
     
        SenderThread sender = new SenderThread(buf, ia , 5556);
        SenderThread sender1 = new SenderThread(buf, ia , 5554);
        sender.start();
        Thread.sleep(500);
        Thread receiver = new ReceiverThread(sender1.getSocket(),ia);
        receiver.start();
    		}
      }
      static Instruction somme (CommandeAT Item1,int compteur)
    	 {
    		 Instruction CodeI = new Instruction("","");
    		 CodeI.CodageI = Item1.Codage+String.valueOf(Item1.param1+compteur)+","+String.valueOf(Item1.param2);
    		 CodeI.InstructionI = Item1.Instruction; 
    	 return CodeI;
    	 }
     
     
    	static Instruction somme1 (CommandeAT Item1,int compteur)//Surdefinition de methode
    	  {
    		  Instruction CodeI = new Instruction("","");
    		  CodeI.CodageI = Item1.Codage+ String.valueOf(Item1.param1 +compteur)+"," +String.valueOf(Item1.param2)+","+String.valueOf(Item1.param3)+","+String.valueOf(Item1.param4)+","+String.valueOf(Item1.param5)+","+String.valueOf(Item1.param6);
    		  CodeI.InstructionI = Item1.Instruction;
    		  return CodeI;
    	  }
     
    	static Instruction somme2 (CommandeAT Item1)//Surdefinition de methode
    	{
    		  Instruction CodeI = new Instruction("","");
    		  CodeI.CodageI = Item1.Codage;
    		  CodeI.InstructionI = Item1.Instruction;
    		  return CodeI;
    	} 
    }
    Ma Classe ReceiverThread:
    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
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
     
    class ReceiverThread extends Thread {
      DatagramSocket socket;
      int port = 5554;
     
      private boolean stopped = false;
     
      public ReceiverThread(DatagramSocket ds,InetAddress ia) throws SocketException {
        this.socket = ds;
        this.socket.connect(ia,port);
      }
     
      public void halt() {
        this.stopped = true;
      }
     
      public void run() {
        byte[] buffer = new byte[1024];
        while (true) {
          if (stopped)  
            return;
          DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
          try {
        	System.out.println(" Port : "+socket.getPort());
        	System.out.println("Inet adresse " + socket.getInetAddress());
            socket.receive(dp);
            String s = new String(dp.getData(), 0, dp.getLength());
            System.out.println(s);
            Thread.yield();
          } catch (IOException ex) {
            System.err.println(ex);
          }
        }

    Encore merci pour vos Réponses

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    donc tu envoie des messages à une machine distante, mais tu ne reçois pas de réponse de cette machine Première chose, est-ce que la machine distante en question reçois bien les message?

  3. #3
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Bonjour
    Oui pas de problème mon deuxième Mac reçoit bien les instructions. Et idem dans ma précédente version avec un temps de pause entre chaque émission le Drone faisait bien les instructions demandées. Le problème est vraiment au niveau de la réception des informations.
    Lorsque j'envoie sur le port 5556 mes instructions il n'y a pas de problème le 2ème mac les reçoit par contre le retour sur le port 5554 il est toujours en attente et j'ai beau faire une boucle infinie du 2ème Mac qui envoi les instructions il n'y a rien.
    J'ai aussi essayé de modifier le port de réception en le mettant en 5556 et en envoyant les données de mon premier Mac sur lui même et toujours rien il reste en attente.
    J'ai vérifié qu'il n'y avait pas de Parefeu .
    Merci encore de vous pencher sur mon cas.
    Cordialement

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Ok, tu as des trucs bizarres dans ton code, c'est le moins que l'on puisse dire.

    D'abord, pourquoi établis-tu trois connections séparée? Tu en établis une, a priori (vu que je n'ai pas ton sender thread) avec le port distant 5556 et une autre avec le port distant 5554 (sender et sender1)
    Ensuite, tu ne démarre que sender, donc seule cette connection communique effectivement avec ton mac. sender1, il ne sert à rien.
    Et enfin, au final, tu établis une troisième connection vers le port 5554 de la machine distante et tu y lis ce qu'elle envoie, a savoir rien, puisqu'on a rien fais dans cette communication.

    Je ne sais pas quel protocole bizaroide tu essaie d'établir, mais en général, on fais les transmissions sur une seule connection.


    Donc ton code vrais plutot être du genre



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        Thread receiver = new ReceiverThread(sender.getSocket());
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    /**
      * Crée un Receiver qui lit les messages arrivant sur cette connection déjà ouverte déjà ouverte
      */
      public ReceiverThread(DatagramSocket ds) throws SocketException {
        this.socket = ds;
      }

    aussi, ce code est inutile:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    StringTokenizer st = new StringTokenizer(ip, ".");
        byte[] ip_bytes = new byte[4];// on traduit l'adresse ensuite en 4 octets
    	if (st.countTokens() == 4)
    	{
     	    for (int i = 0; i < 4; i++)
     	    {
    		ip_bytes[i] = (byte)Integer.parseInt(st.nextToken());
    	    }
    	}
    	InetAddress ia = InetAddress.getByAddress(ip_bytes);
    tu peux directement écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	InetAddress ia = InetAddress.getByName(ip);

  5. #5
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Re Bonjour TCHIZE
    Avant tout merci pour votre réponse j'essaye de tester cela ce soir. Néanmoins j'ai besoin de 2 Sockets en effet le Drone Parrot (cf le Mode d'emploi du SDK) précise qu'il reçoit des instructions sur la socket 5556 et qu'il retourne ses mesures sur la socket 5554 . le tout avec un protocole UDP. C'est pour cela que j'ai créé 2 objets (sender et sender1) et que j'ai essayé de faire du Thread . Mais je suis débutant et non professionnel donc peut être que je m'y prends mal pour programmer cela.
    En vous remerciant de votre réponse et de vos conseils
    Bien Cordialement

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    ok, je comprends. donc en fait le drone a une connection bi-directionnelle sur le 5556 qui gère les commandes. Donc a priori les messages d'erreurs reviendront de là. Et une deuxième connection sur le port 5554 qui permet d'interroger les valeurs.

    Dans tous les cas, ces socket, sauf particularité bizarre du drone, doivent être initiées par toi et tu dois envoyer des commandes pour que le drone réponde

  7. #7
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Connexion bidirectionnelle
    Voila c'est tout à fait cela. J'envoie en 5556 et le drone doit me répondre en 5554. D'ou mes deux objet sender et sender1 mais avec des sockets différentes. C'était pour moi une façon d'essayer de communiquer avec le Drone mais voilà le retour ne se passe pas comme prévu...
    En vous remerciant de l'attention que vous portez à mon problème
    Bien Cordialement

  8. #8
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Encore un petit coup de main
    Bonsoir TCHIZE ,
    Avant tout merci pour vos réflexions pertinentes. J'ai déjà du mieux mais je dois gérer un problèmes de ports occupés. Si je crée deux objets indépendant donc avec des Threads indépendants par exemple un objet reception5554 (avec un senderThread5554 et un receiveThread5554) et la même chose avec un objet emission5556 (avec un senderThread5556 et un receiveThread5556) ai je des chances de réussir ou bien faut il procéder autrement encore dans le cadre d'une connexion bidirectionnelle sur deux ports différents?
    En attendant de vous lire.
    Bien cordialement , et grands Mercis pour vos messages toujours très pertinents

  9. #9
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Tu ne devrais pas avoir un problème de ports occupés. Je n'ai pas lu le SDK de ton drone, mais en général, les ports "source" sont aléatoire, il en reste suffisament de libre, et on eut être plusieurs simultanément sur le port "destination". Si tu as un problème de port occupé, soumet ton code, on corrigera.

  10. #10
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Bonsoir Mr TCHIZE
    Une petite semaine s'est écoulée , j'ai profondément revu mon programme , j'ai bien reçu une instruction dur une dizaine en retour donc la connexion Mac-Mac marche à peu près ... néanmoins j'ai toujours un message d'erreur : "java.net.BindException: Address already in use" j'ai certainement du oublier certaines choses (mais comme je vous l'ai déjà dit l'informatique n'est pas ma profession juste une passion c'est aussi pour cela que je me considère comme débutant) je vous joins mon code que j'ai complètement réécris cette semaine et inspiré des Threads du bouquin de Mr DELANNOY.

    Mon Main:

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    import java.net.InetAddress;
     
     
    public class MainClass {
     
      public static void main(String[] args) throws Exception {
      //  String hostname = "localhost";
    	  CommandeAT [] Item;
    		Item = new CommandeAT[11];
    		Item[0] = new CommandeAT ("Decollage","AT*REF=",100,290718208);// Faire une incremenatation des N° de sequence et ... recup etat de la batterie
    		Item[1] = new CommandeAT ("Atterrissage","AT*REF=",100,290717696);
    		Item[2] = new CommandeAT ("Stationnaire","AT*PCMD=",100,1,0,0,0,0);
    		Item[3] = new CommandeAT ("plusdegaz","AT*PCMD=",100,1,0,0,1036831949,0);
    		Item[4] = new CommandeAT ("moinsdegaz","AT*PCMD=",100,1,0,0,-1110651699,0);
    		Item[5] = new CommandeAT ("plusdeTangage","AT*PCMD=",100,1,1036831949,0,0,0);
    		Item[6] = new CommandeAT ("moinsdeTangage","AT*PCMD=",100,1,-1110651699,0,0,0);
    		Item[7] = new CommandeAT ("plusMvtLacet","AT*PCMD=",100,1,0,0,0,1036831949);
    		Item[8] = new CommandeAT ("moinsMvtLacet","AT*PCMD=",100,1,0,0,0,-1110651699);
    		Item[9] = new CommandeAT ("plusderoulis","AT*PCMD=",100,1,0,1036831949,0,0);
    		Item[10] = new CommandeAT ("Init","AT*CONFIG=1,\"control:altitude_max\",\"2000\"");
    		Instruction AT = new Instruction("","");
    		int sequence=0;
    		int ordre[] = {10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1};
    		String ip = "192.168.0.36"; // adresse d'envoie à modifier en fonction du macintosh ou du drone
     
        //////////////////////////////////////////////////////////////////////////////
        				//		Codage adresse    //
        ////////////////////////////////////////////////////////////////////////////
        InetAddress ia = InetAddress.getByName(ip);
    //////////////////////////////////////////////////////////////////////////////
    	//                  Envoie de la sequence et de la reception		//
    //////////////////////////////////////////////////////////////////////////////	
    	 for (int j=0 ;j< ordre.length; j++)
    		{	
    			if (Item[ordre[j]].Codage=="AT*REF=") {AT = somme (Item[ordre[j]],sequence);} else 
    			if (Item[ordre[j]].Codage=="AT*CONFIG=1,\"control:altitude_max\",\"2000\"") {AT = somme2 (Item[10]);} else// voir instruction a envoyer;
    			if (Item[ordre[j]].Codage=="AT*PCMD="){AT = somme1 (Item[ordre[j]],sequence);}
    			String a = AT.CodageI;
     
         	byte[] buf = (a + "\r").getBytes();
    	//
     //    	Definir un objet à mettre dans new ReceiverThread() et dans new SenderThread() 
         // definition de Monobjet
     
         	Monobjet obj = new Monobjet(buf,ia,5556,true);
         	Monobjet obj1 = new Monobjet(buf,ia,5554,false);
         	// Gestion de mes Thread
     
    	Thread recois = new ReceiverThread(obj1);
    	Thread envoi = new SenderThread(obj);
    	envoi.start();
    	Thread.sleep(500);
    	recois.start();
    		}
      }
      static Instruction somme (CommandeAT Item1,int compteur)
    	 {
    		 Instruction CodeI = new Instruction("","");
    		 CodeI.CodageI = Item1.Codage+String.valueOf(Item1.param1+compteur)+","+String.valueOf(Item1.param2);
    		 CodeI.InstructionI = Item1.Instruction; 
    	 return CodeI;
    	 }
     
     
    	static Instruction somme1 (CommandeAT Item1,int compteur)//Surdefinition de methode
    	  {
    		  Instruction CodeI = new Instruction("","");
    		  CodeI.CodageI = Item1.Codage+ String.valueOf(Item1.param1 +compteur)+"," +String.valueOf(Item1.param2)+","+String.valueOf(Item1.param3)+","+String.valueOf(Item1.param4)+","+String.valueOf(Item1.param5)+","+String.valueOf(Item1.param6);
    		  CodeI.InstructionI = Item1.Instruction;
    		  return CodeI;
    	  }
     
    	static Instruction somme2 (CommandeAT Item1)//Surdefinition de methode
    	{
    		  Instruction CodeI = new Instruction("","");
    		  CodeI.CodageI = Item1.Codage;
    		  CodeI.InstructionI = Item1.Instruction;
    		  return CodeI;
    	} 
    }
    Ma nouvelle classe Monobjet qui permet de gerer le sender et le receive en synchronized :

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
     
    public class Monobjet {
     
     
    	byte[] buffer; 
    	InetAddress adress ;
    	int port;
    	boolean selection;
    	// Variable buffer pour les packets à envoyer , adress et port pour l'adresse et le port sur lesquels on envoie. selection pour un envoie ou une reception
    	public Monobjet (int pt,boolean selec) 
    	{
    		port = pt ;
    		selection = selec;
    	}
     
    	public Monobjet (InetAddress adr,int pt,boolean selec) 
    	{
    		adress = adr;
    		port = pt ;
    		selection = selec;
    	}
     
    	public Monobjet (byte[] buf,InetAddress adr,int pt,boolean selec) 
    	{
    		buffer = buf;
    		adress = adr;
    		port = pt ;
    		selection = selec;
    	}
     
     
    	public synchronized void sender(byte[] buffer, boolean selection,int port,InetAddress adress) throws SocketException
    	{	
    		DatagramSocket socket;
    		DatagramPacket packet;
    		if (selection != true) return; // port d'envoi selectionné si true
    		socket = new DatagramSocket();
    		socket.connect(adress, port);
    		try {
    	        byte[] data = buffer;     
    	        packet = new DatagramPacket(data, data.length, adress, port);
    	        socket.send(packet);
    	        System.out.println("j'envoie :"+packet);
    	        Thread.yield();
    	    }
    	    catch (IOException ex) {
    	      System.err.println(ex);
    	    }
     
    	}
     
    	public synchronized void receive( int port, boolean selection) throws SocketException
    	{	
    		boolean emis = false;
    		DatagramSocket socket;
    		DatagramPacket packet;
    		System.out.println(" je recois .0... ");
    		if (selection == true) {System.out.println(" je recois ..3.. "+port+"   "+selection);return;} // port de reception selectionné si false
    		 byte[] buffer = new byte[1024];
    		 try {
    			 socket= new DatagramSocket (port);
     	 		} catch (SocketException e) 
     	 		{
     	 		System.out.println(e);
     	 		return;
     	 		}
    		 	packet = new DatagramPacket(buffer, buffer.length);
    		 	 while (emis!=true) {
    		 		System.out.println(" je recois .1... ");
    		 			try {
    		 				System.out.println(" je recois ..2.. ");
    		 				socket.receive(packet);
    		 				String  s = new String(buffer,0,0,packet.getLength());
    		 				System.out.println("reception s : "+s);
    		 				emis = true;
    		 				} catch (IOException ioe) 
    		 				{
    		 				System.out.println(ioe);
    		 				}
    	 				}
    	}
     
     
    }
    Ma classe ReceiverThread:

    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
    import java.io.IOException;
     
     
    class ReceiverThread extends Thread 
    { private Monobjet obj;
     
    	public ReceiverThread (Monobjet obj)
    {
    	this.obj = obj;	// peut être revoir ici
    }
     
    	public void run ()
    	{
        try {
     
            obj.receive(obj.port,obj.selection) ;
            Thread.yield();
        }
        catch (IOException ex) {
          System.err.println(ex);
        }
    	}
    }
    Ma classe SenderThread:


    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
    import java.io.IOException;
     
     
    class SenderThread extends Thread {
     
    	private Monobjet obj;
     
      public SenderThread (Monobjet obj) 
      {
    	  this.obj = obj;	// peut être revoir ici
      }
     
      public void run ()
    	{
      try {
     
          obj.sender(obj.buffer,obj.selection,obj.port,obj.adress) ;// revoir ici dans les parametres a envoyer
          Thread.yield();
      }
      catch (IOException ex) {
        System.err.println(ex);
      }
    	}
    }
    Ma classe CommandAT :


    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
    class CommandeAT {
    	String Instruction;
    	String Codage;
    	int param1,param2,param3,param4,param5,param6;
     
     
    	// Constructeur par default
    	public CommandeAT()
    	{
    		Instruction = "Non renseignée";
    		Codage = "Modele de base";
    	}	
     
     
    	// Constructeur avec parametres
     
    	public CommandeAT(String Mque,String Mod)
    	{
    		Instruction = Mque;
    		Codage = Mod;
     
     
    	}
     
    	public CommandeAT(String Mque,String Mod,int p1,int p2)
    	{
    		Instruction = Mque;
    		Codage = Mod;
    		param1=p1;
    		param2=p2;
     
    	}
     
    	public CommandeAT(String Mque,String Mod,int p1,int p2,int p3,int p4,int p5,int p6)
    	{
    		Instruction = Mque;
    		Codage = Mod;
    		param1=p1;
    		param2=p2;
    		param3=p3;
    		param4=p4;
    		param5=p5;
    		param6=p6;	
    	}
     
     
    }
    Et enfin Ma classe Instruction :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Instruction extends CommandeAT{
    	String InstructionI;
    	String CodageI;
    	public Instruction (String Instruc,String Code)
    	{
    		InstructionI = Instruc;
    		CodageI = Code;
    	}
    	}


    En vous remerciant de l'attention que vous prêtez à mon problème de connexion Bidirectionnelle et en attente de vous lire.
    Bien Cordialement
    Johanndebutant

    nb: Un tutoriel sur de la connexion bidirectionnelle en java serait aussi le bien venu ....

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Ce serait utile que tu nous mettre la trace complète de ton erreur On n'a pas la moindre idée d'où et dans quelles conditions se produit ton BindException

    Donc remplace

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.err.println(ex);
    par
    Sinon, dans ton receive tu fais ceci:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    socket= new DatagramSocket (port);
    Ce qui fait que tu te branche localement sur le port 5556 en local. Hors tu le fais pour chaque message de ta boucle dans le main. Ce qui veux dire que tu essaie de te brancher 3 fois sur ce port. Hors on ne peut avoir qu'une seule application branchée à la fois sur un port local, car cela permet de savoir vers quelle application / procédure il faut transférer les informations qui y arrivent. Donc tu as une erreur à ta deuxième itération boucle. Je vais te dire en gros ce qui risque de se passer avec ton code, et je crois que tu comprendra ton erreur:

    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
    ton code                                    ton serveur
    
    preparation du message 1
    préparation des threads envoi E1 / réception R1
     E1: binding sur 5554 coté serveur
     E1: envoi message 1                       
    sleep de 500 ms
                                                réception message 1
                                                envoie réponse 1, personne pour le réceptionner car tu es dans le sleep
    R1 démarre
     R1 binding local sur port 5556
     R1 attente d'un message
    préparation du message 2
    
    préparation des threads envoi E2/ réception R2
     E1: binding sur 5554 coté serveur
     E1: envoi message 1                       
    sleep de 500 ms
                                                réception message 2
                                                envoie réponse 2
     R1: réception réponse 2
     R2 démarre
     R2 binding local sur port 5556 
               =>erreur, déjà bindé par R1!
    Ce que tu ne dois pas faire:

    • démarrer une paire de thread pour chaque message.
    • démarrer le thread d'envoi avant celui de réception (risque de rater une réponse si on es trop lent)
    • appeler Thread.yield() -> pollue le code et ne sert à rien
    • se binder autant de fois qu'il y a de message -> risque de saturation des socket, conflit entre les bind si même numéro de port




    ce que tu dois faire:
    • un thread d'envoi et un thread de réception seulement
    • chaque thread boucle dans son run: celui d'envoi sur les messages à envoyer, celui de réception sur les messages à recevoir.
    • démarrer le thread de réception avant le thread d'envoi

  12. #12
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Bonsoir Mr TCHIZE
    Comme à chaque fois que je vous lis j'apprends des choses , je me replonge dans les bouquins pour m'apercevoir et corriger mes nombreuses lacunes. Ainsi en vous lisant vous dite que j'appelle plusieurs fois le même port ainsi pour corriger cela , ne faut il pas que je modifie la classe Monobjet en y incluant un datagramSocket afin d'ouvrir le port une bonne fois pour toute?
    on obtiendrait alors quelquechose comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	Monobjet obj = new Monobjet(buf,ia,5556,true,MondatagramSocket);
    De même vous me dite il faut faire passer d'abord la réception avant l'émission alors de même si j'écris la chose suivante est ce que cela traduit correctement votre réflexion?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Thread recois = new ReceiverThread(obj1);
    	Thread envoi = new SenderThread(obj);
    	recois.start();
    	Thread.sleep(500);
            envoi.start();
    En attente de vous lire et pour rejoindre de nombreux lecteurs soyez certain de toute ma reconnaissance et ma gratitude.
    Bien cordialement
    johanndebutant

  13. #13
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par johanndebutant Voir le message
    ne faut il pas que je modifie la classe Monobjet en y incluant un datagramSocket afin d'ouvrir le port une bonne fois pour toute?
    Ca peut être une solution. Mais alors tu risque des problèmes au niveau de tes threads. tu n'ouvre la socket qu'une fois (normal) mais plusieurs thread 'envoi' tournent dessus. Ils risquent de se battre pour la socket si le premier thread n'a pas fini avant que le deuxième ne commence. Tu dois faire attention à ca.

    Ceci dit, si tu ne fais qu'un seul thread d'envoi et un seul thread de réception, ton défis sera de gérer la communication entre ces deux threads, genre le réception qui dit à l'envoi, "j'ai reçu ça, envoie la suite". Bref, chaque solution a ses problèmes à gérer

    Citation Envoyé par johanndebutant Voir le message
    on obtiendrait alors quelquechose comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	Monobjet obj = new Monobjet(buf,ia,5556,true,MondatagramSocket);
    Autant que monobjet, dans son constructeur, fasse l'ouverture du datagramSocket, il a déjà toutes les informations nécessaire (port, adresse, ...)


    Citation Envoyé par johanndebutant Voir le message
    De même vous me dite il faut faire passer d'abord la réception avant l'émission alors de même si j'écris la chose suivante est ce que cela traduit correctement votre réflexion?
    une solution pauvre, mais suffisante pour débuter Si SenderThread met plus de 500ms à démarrer, l'envoi commencera avant d'être prêt à recevoir. Généralement on établis toutes les connexions dans l'ordre et ensuite on délègue la gestion de ces connexions aux différents threads. Cf la suggestion de mettre la socket dans le MonObject

  14. #14
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Bonjour Mr TCHIZE
    J'ai fait quelques modifications afin d'éviter de répéter la socket 5556 qui bloque tout: j'ai mis finalement une variable globale et fait un test dans ma méthode. Je n'ai plus d'erreur "Bind" mais l'affichage de string s se produit bien une fois puis ensuite il affiche bien "réception s " avec rien derrière.
    nb j'ai fais les tests sur mon propre Mac en modifiant l'IP (adresse de mon Mac de développement) et le port de réception a été modifié j'ai mis le même que celui qui envoie afin d'avoir en retour ce que j'envoie ....

    voici mon nouveau code:
    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
     
    public class Monobjet {
    	public static int mavariableglobale =0;
    	byte[] buffer; 
    	InetAddress adress ;
    	int port;
    	boolean selection;
    	// Variable buffer pour les packets à envoyer , adress et port pour l'adresse et le port sur lesquels on envoie. selection pour un envoie ou une reception
    	public Monobjet (int pt,boolean selec) 
    	{
    		port = pt ;
    		selection = selec;
    	}
     
    	public Monobjet (InetAddress adr,int pt,boolean selec) 
    	{
    		adress = adr;
    		port = pt ;
    		selection = selec;
    	}
     
    	public Monobjet (byte[] buf,InetAddress adr,int pt,boolean selec) 
    	{
    		buffer = buf;
    		adress = adr;
    		port = pt ;
    		selection = selec;
    	}
     
     
    	public synchronized void sender(byte[] buffer, boolean selection,int port,InetAddress adress) throws SocketException
    	{	
    		DatagramSocket socket;
    		DatagramPacket packet;
    		if (selection != true) return; // port d'envoi selectionné si true
    		socket = new DatagramSocket();
    		socket.connect(adress, port);
    		try {
    	        byte[] data = buffer;     
    	        packet = new DatagramPacket(data, data.length, adress, port);
    	        socket.send(packet);
    	        System.out.println("j'envoie :"+packet);
    	    }
    	    catch (IOException ex) {
    	    	ex.printStackTrace();
    	    }
     
    	}
     
    	public synchronized void receive( int port, boolean selection) throws SocketException
    	{	
    		mavariableglobale++;
    		boolean emis = false;
    		DatagramPacket packet;
    		//DatagramSocket socket;
    		System.out.println(" je recois .0... ");
    		if (selection == true) {System.out.println(" je recois ..3.. "+port+"   "+selection);return;} // port de reception selectionné si false
    		 byte[] buffer = new byte[1024];
     
    		 if (mavariableglobale>1) {System.out.println ("affiche :"+mavariableglobale);
    		 							packet = new DatagramPacket(buffer, buffer.length);
    		 							// ne marche pas car pas de receive() mais si présence alors erreur
    		 							String  s = new String(buffer,0,0,packet.getLength());
    		 							System.out.println("reception s : "+s);
    		 							return;}
    		 DatagramSocket socket;
    		 try {
    			 socket= new DatagramSocket (port);
     	 		} catch (SocketException e) 
     	 		{
     	 			e.printStackTrace();
    					return;
     	 		}
    		 	packet = new DatagramPacket(buffer, buffer.length);
    		 	 while (emis!=true) {
    		 		System.out.println(" je recois .1... ");
    		 			try {
    		 				System.out.println(" je recois ..2.. ");
    		 				socket.receive(packet);
    		 				String  s = new String(buffer,0,0,packet.getLength());
    		 				System.out.println("reception s : "+s);
    		 				emis = true;
    		 				} catch (IOException ioe) 
    		 				{
    		 					ioe.printStackTrace();
    		 				}
    	 				}
    	}
     
     
    }

    j obtiens ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    java.io.IOException: Host is down
     je recois .0... 
    affiche :43
    reception s : 
    java.io.IOException: Host is down
     je recois .0... 
    affiche :44
    reception s : 
    java.io.IOException: Host is down
    Je pensais que je n'étais pas très loin ... mais depuis ce soir je rame grave!!!
    En vous remerciant d'avance de tout ce que vous faite pour moi et en attente de vous lire.
    Bien Cordialement
    johanndebutant

  15. #15
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Encore un peu d'aide Mr TCHIZE s'il vous plait
    Bonjour Mr TCHIZE ,
    Après avoir bien galéré hier soir , j'ai décidé de reprendre tout à plat et de reprendre tous vos messages et essayé de les réinterpréter. La nuit portant conseil voici quelques réflexions pour lesquelles je vais avoir besoin de votre confirmation ou non quant à l'interprétation de vos remarques:

    "un thread d'envoi et un thread de réception seulement" Dois je alors avoir simplement*:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    un main() avec un start.threadrecois ,  un start.threadenvoi*;
    un threadrecois
    un threadenvoi
    (et naturellement ma classe Atcommand et ma classe Instruction)
    "chaque thread boucle dans son run: celui d'envoi sur les messages à envoyer, celui de réception sur les messages à recevoir."

    Par exemple pour la réception*:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Threadrecois extends Thread {
        Threadrecois() {
                ... code du constructeur*:en reprenant les differents parametres de Monobjet, en declarant un datagramSocket socket
        }
     
        public void run() {
                ... code a executer dans le thread*: en reprenant le code avec DatagramPacket packet ,..., socket.receive()*; ….
     
        }
    }
    "démarrer le thread de réception avant le thread d'envoi"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dans le Main() mettre d'abord    threadreception.start () puis threadenvoi.start()

    Après une soirée plutôt déprimante j'espère pouvoir trouver la solution aujourd'hui grâce à vos réflexions toujours très pertinentes.
    En attente de vous lire.
    Bien cordialement
    johanndebutant

  16. #16
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut Ou se trouve mon erreur
    Bonsoir j'ai remodifié complètement mon programme en essayant de suivre les conseils de Monsieur TCHIZE mais voilà j'ai bien une reception mais ensuite ça ne s'enchaine pas voici mon code (je joinds le Main() et le Thread

    Le Main():

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    import java.net.InetAddress;
     
     
    public class MainClass {
     
      public static void main(String[] args) throws Exception {
      //  String hostname = "localhost";
    	  CommandeAT [] Item;
    		Item = new CommandeAT[11];
    		Item[0] = new CommandeAT ("Decollage","AT*REF=",100,290718208);// Faire une incremenatation des N° de sequence et ... recup etat de la batterie
    		Item[1] = new CommandeAT ("Atterrissage","AT*REF=",100,290717696);
    		Item[2] = new CommandeAT ("Stationnaire","AT*PCMD=",100,1,0,0,0,0);
    		Item[3] = new CommandeAT ("plusdegaz","AT*PCMD=",100,1,0,0,1036831949,0);
    		Item[4] = new CommandeAT ("moinsdegaz","AT*PCMD=",100,1,0,0,-1110651699,0);
    		Item[5] = new CommandeAT ("plusdeTangage","AT*PCMD=",100,1,1036831949,0,0,0);
    		Item[6] = new CommandeAT ("moinsdeTangage","AT*PCMD=",100,1,-1110651699,0,0,0);
    		Item[7] = new CommandeAT ("plusMvtLacet","AT*PCMD=",100,1,0,0,0,1036831949);
    		Item[8] = new CommandeAT ("moinsMvtLacet","AT*PCMD=",100,1,0,0,0,-1110651699);
    		Item[9] = new CommandeAT ("plusderoulis","AT*PCMD=",100,1,0,1036831949,0,0);
    		Item[10] = new CommandeAT ("Init","AT*CONFIG=1,\"control:altitude_max\",\"2000\"");
    		Instruction AT = new Instruction("","");
    		int sequence=0;
    		int ordre[] = {10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1};
    		String ip = "192.168.0.16"; // adresse d'envoie à modifier en fonction du macintosh ou du drone
     
        //////////////////////////////////////////////////////////////////////////////
        				//		Codage adresse    //
        ////////////////////////////////////////////////////////////////////////////
        InetAddress ia = InetAddress.getByName(ip);
    //////////////////////////////////////////////////////////////////////////////
    	//                  Envoie de la sequence et de la reception		//
    //////////////////////////////////////////////////////////////////////////////	
    	 for (int j=0 ;j< ordre.length; j++)
    		{	
    			if (Item[ordre[j]].Codage=="AT*REF=") {AT = somme (Item[ordre[j]],sequence);} else 
    			if (Item[ordre[j]].Codage=="AT*CONFIG=1,\"control:altitude_max\",\"2000\"") {AT = somme2 (Item[10]);} else// voir instruction a envoyer;
    			if (Item[ordre[j]].Codage=="AT*PCMD="){AT = somme1 (Item[ordre[j]],sequence);}
    			String a = AT.CodageI;
     
         	byte[] buf = (a + "\r").getBytes();
    	//
     //    	Definir un objet à mettre dans new ReceiverThread() et dans new SenderThread() 
         // definition de Monobjet
     
     
         	// Gestion de mes Thread
         	Monobjet obj = new Monobjet(5556,true);
         	Monobjet obj1 = new Monobjet(5554,false);
    	Thread recois = new ThreadSocket(obj);
    	Thread envoi = new ThreadSocket(obj1);
    	recois.start();
    	Thread.sleep(5);
    	envoi.start();
    		}
      }
      static Instruction somme (CommandeAT Item1,int compteur)
    	 {
    		 Instruction CodeI = new Instruction("","");
    		 CodeI.CodageI = Item1.Codage+String.valueOf(Item1.param1+compteur)+","+String.valueOf(Item1.param2);
    		 CodeI.InstructionI = Item1.Instruction; 
    	 return CodeI;
    	 }
     
     
    	static Instruction somme1 (CommandeAT Item1,int compteur)//Surdefinition de methode
    	  {
    		  Instruction CodeI = new Instruction("","");
    		  CodeI.CodageI = Item1.Codage+ String.valueOf(Item1.param1 +compteur)+"," +String.valueOf(Item1.param2)+","+String.valueOf(Item1.param3)+","+String.valueOf(Item1.param4)+","+String.valueOf(Item1.param5)+","+String.valueOf(Item1.param6);
    		  CodeI.InstructionI = Item1.Instruction;
    		  return CodeI;
    	  }
     
    	static Instruction somme2 (CommandeAT Item1)//Surdefinition de methode
    	{
    		  Instruction CodeI = new Instruction("","");
    		  CodeI.CodageI = Item1.Codage;
    		  CodeI.InstructionI = Item1.Instruction;
    		  return CodeI;
    	} 
    }
    et le Thread():
    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
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
     
     
    public class ThreadSocket extends Thread
    {
    	DatagramSocket socket ;
    	DatagramPacket packet;
    	int port=5556;
    	public static int mavariableglobale =0;
    	public static boolean aiguillage = true;
     
    	public ThreadSocket (Monobjet objet) throws SocketException
    	{
     
    		aiguillage = objet.selection;
    		if (mavariableglobale==0) {  // pour n'ouvrir qu'une fois la socket
    		try {
    			mavariableglobale++;
    			System.out.println("mise en route server");
    	 		socket = new DatagramSocket(port);
    	 		} catch (SocketException e) 
    	 		{
    	 		e.printStackTrace();
    	 		return;
    	 		}};
    	}
    public void run()
    {  
    	if (aiguillage==true) {					// si true alors mode reception ; si false alors mode envoi à developper qd reception marchera
    	byte[] buffer = new byte[1024];
    	System.out.println("envoi du run :"+ mavariableglobale); // pour savoir ou je suis et quel est la valeur de mavariableglobale
    	 	 while (mavariableglobale==1) {					//pour ne pas réouvrir à chaque fois la socket 5556
    	 			try {
    	 				packet= new DatagramPacket(buffer,buffer.length);
    	 				System.out.println(" je recois ..try. "+port+"   "+mavariableglobale);
    	 				socket.receive(packet);
    	 				String  s = new String(buffer);
    	 				System.out.println("reception s : "+ s);
     
    	 				} catch (IOException ioe) 
    	 				{
    	 				ioe.printStackTrace();
    	 				}
    				}
    							} else System.out.println("envoi");
    }
    }

    et voici ce que j'obtiens ensuite:
    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
    mise en route server
    envoi
    envoi
    envoi
    envoi
    envoi
    envoi
    envoi
    envoi
    envoi
    envoi
    envoi
    envoi du run :1
     je recois ..try. 5556   1
    Exception in thread "Thread-12" java.lang.NullPointerException
    	at ThreadSocket.run(ThreadSocket.java:39)
    envoi
    Pouvez vous m'aider. En vous remerciant d'avance.
    johanndebutant

  17. #17
    Membre du Club
    Homme Profil pro
    Medecin Biologiste
    Inscrit en
    Janvier 2013
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Medecin Biologiste
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2013
    Messages : 64
    Points : 49
    Points
    49
    Par défaut UDP et Thread (Enfin ça marche!)
    Après quelques soirées et un Samedi à bosser dessus en ayant en tête les remarque de Monsieur TCHIZE et en relisant les différents tutoriaux de Developpez.com et de Mr CARIOU j'ai enfin trouvé la solution . je la joins afin d'éviter peut être à certains de galérer comme moi. Je tiens à remercier Monsieur TCHIZE pour sa patience , sa disponibilité et ses remarques très constructive. Un grand merci également à Developpez.com pour tous les tutoriaux disponibles . Mes remerciements également à Mr CARIOU pour son cours en ligne sur l'UDP en Java.

    Voici mon code :

    Le Main :
    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    import java.net.DatagramSocket;
    import java.net.InetAddress;
     
     
    public class MainClass {
    	public boolean actif;
     
      public static void main(String[] args) throws Exception {
      //  String hostname = "localhost";
    	  CommandeAT [] Item;
    		Item = new CommandeAT[11];
    		Item[0] = new CommandeAT ("Decollage","AT*REF=",100,290718208);// Faire une incremenatation des N° de sequence et ... recup etat de la batterie
    		Item[1] = new CommandeAT ("Atterrissage","AT*REF=",100,290717696);
    		Item[2] = new CommandeAT ("Stationnaire","AT*PCMD=",100,1,0,0,0,0);
    		Item[3] = new CommandeAT ("plusdegaz","AT*PCMD=",100,1,0,0,1036831949,0);
    		Item[4] = new CommandeAT ("moinsdegaz","AT*PCMD=",100,1,0,0,-1110651699,0);
    		Item[5] = new CommandeAT ("plusdeTangage","AT*PCMD=",100,1,1036831949,0,0,0);
    		Item[6] = new CommandeAT ("moinsdeTangage","AT*PCMD=",100,1,-1110651699,0,0,0);
    		Item[7] = new CommandeAT ("plusMvtLacet","AT*PCMD=",100,1,0,0,0,1036831949);
    		Item[8] = new CommandeAT ("moinsMvtLacet","AT*PCMD=",100,1,0,0,0,-1110651699);
    		Item[9] = new CommandeAT ("plusderoulis","AT*PCMD=",100,1,0,1036831949,0,0);
    		Item[10] = new CommandeAT ("Init","AT*CONFIG=1,\"control:altitude_max\",\"2000\"");
    		Instruction AT = new Instruction("","");
    		int sequence=0;
    		int ordre[] = {10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1,10,0,2,1};
     
        //////////////////////////////////////////////////////////////////////////////
        				//		Declaration  socket    //
        ////////////////////////////////////////////////////////////////////////////
        String ip = "192.168.0.16";
    	InetAddress ia = InetAddress.getByName(ip);
        int port =5554;
    	DatagramSocket Socket1;
    	Socket1 = new DatagramSocket(port,ia);
    //////////////////////////////////////////////////////////////////////////////
    	//                  Envoie de la sequence et de la reception		//
    //////////////////////////////////////////////////////////////////////////////	
    	 for (int j=0 ;j< ordre.length; j++)
    		{	
    			if (Item[ordre[j]].Codage=="AT*REF=") {AT = somme (Item[ordre[j]],sequence);} else 
    			if (Item[ordre[j]].Codage=="AT*CONFIG=1,\"control:altitude_max\",\"2000\"") {AT = somme2 (Item[10]);} else// voir instruction a envoyer;
    			if (Item[ordre[j]].Codage=="AT*PCMD="){AT = somme1 (Item[ordre[j]],sequence);}
    			String a = AT.CodageI;
     
         	byte[] buf = (a + "\r").getBytes();
     
      ////////////////////////////////////////////////////////////////////////////   	
      //                         Gestion des Threads	                       //
     /////////////////////////////////////////////////////////////////////////////
     
        Thread.sleep(500);
        Thread receiver = new ReceiverThread(Socket1);
        receiver.setDaemon(true);
        receiver.start();
    		}
      }
      static Instruction somme (CommandeAT Item1,int compteur)
    	 {
    		 Instruction CodeI = new Instruction("","");
    		 CodeI.CodageI = Item1.Codage+String.valueOf(Item1.param1+compteur)+","+String.valueOf(Item1.param2);
    		 CodeI.InstructionI = Item1.Instruction; 
    	 return CodeI;
    	 }
     
     
    	static Instruction somme1 (CommandeAT Item1,int compteur)//Surdefinition de methode
    	  {
    		  Instruction CodeI = new Instruction("","");
    		  CodeI.CodageI = Item1.Codage+ String.valueOf(Item1.param1 +compteur)+"," +String.valueOf(Item1.param2)+","+String.valueOf(Item1.param3)+","+String.valueOf(Item1.param4)+","+String.valueOf(Item1.param5)+","+String.valueOf(Item1.param6);
    		  CodeI.InstructionI = Item1.Instruction;
    		  return CodeI;
    	  }
     
    	static Instruction somme2 (CommandeAT Item1)//Surdefinition de methode
    	{
    		  Instruction CodeI = new Instruction("","");
    		  CodeI.CodageI = Item1.Codage;
    		  CodeI.InstructionI = Item1.Instruction;
    		  return CodeI;
    	} 
    }
    et le ThreadReceiver :

    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
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
     
    public  class ReceiverThread extends Thread {
      boolean  actif;
      int port = 5554;
      DatagramSocket socketR;
     
     
      public ReceiverThread(DatagramSocket socket)  {
    	  socketR = socket;	  
    	  actif = true;
      }
     
      public void run() {
        byte[] buffer = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
        String s;
     // ne pas repeter la boucle si la socket est ouverte pour ne pas la multiplier d'ou booleen actif
        while (actif) {
     
     
          try {
        	System.out.println("j'attends");
        	socketR.receive(dp);
        	s = new String(dp.getData(),0, dp.getLength());
        	System.out.println("je recois : "+s);
     
          } catch (IOException ex) {
            System.out.println(ex);
            actif = false;
          }
        }
     
      }
    }
    nb: je considère le problème comme résolu. Je cliquerai sur la touche résolu dans quelques jours au cas ou Mr TCHIZE veuille rajouter un commentaire .

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

Discussions similaires

  1. Réception UDP avec des sockets
    Par Gregory_007 dans le forum Réseau
    Réponses: 18
    Dernier message: 20/07/2012, 03h49
  2. Thread de réception de flux
    Par Shicky dans le forum Threads & Processus
    Réponses: 2
    Dernier message: 13/05/2011, 21h38
  3. Thread sur socket udp
    Par reitsab dans le forum WinDev
    Réponses: 2
    Dernier message: 23/02/2010, 14h57
  4. pb réception UDP avec transfert rapide
    Par loup_precaire dans le forum Réseau
    Réponses: 4
    Dernier message: 23/03/2009, 22h22
  5. Réception UDP et test de chaine
    Par molotov dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 28/03/2008, 18h14

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