Simplemessenger : messagerie (presque !) instantanée via udp

Soyez le premier à donner votre avis sur cette source.

Vue 14 004 fois - Téléchargée 1 556 fois

Description

Cette petite application permet de communiquer via un réseau local en s'envoyant des messages textes. Bien sur, elle serai largement améliorable(en ajoutant du texte en couleur, une liste de contactes, etc ...). Ici, je pose simplement les bases réseaux (j'utilise un marqueur de fin de message, car dans le cas contraire il serai affiché des "carrés" (signe binaire) remplissant les espaces vides. Je n'ai pas passé du temp à imaginer une autre technique.

Source / Exemple :


package yann.reseau;

import java.net.*;
import java.io.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

/* Dans un version plus récente(la finale) située malheuresement sur mon autre ordinateur, j'avais implementé un marqueur de fin de ligne(du genre [END]) car lors de l'affichage, on s'aperçois de l'apparition de caractères [] pour chaque octet vide reçus, soit 2048 moins la longueur du message, ce qui fait beaucoup... */

public class Conversation implements Runnable, ActionListener {
   GridBagConstraints gbc = new GridBagConstraints();
   JTextArea area = new JTextArea(); //affichage des messages
   int port = 5000; //port par défaut
   String destinataire = "OEMComputer"; //destinataire par defaut(en fait le nom de ma machine)
   JTextField field = new JTextField(15); //champ où entrer le message
   Thread thread;
   JFrame frame = new JFrame("Yann Messenger v1.0");
   JButton button2; 
   
   //renvoi le nom local
   public String localHost() {
      try {
         return InetAddress.getLocalHost().getHostName();
      }
      catch (UnknownHostException uhe) {
         return "moi";
      }
   }

   //méthode ajoutant des composants aux coordonnées souhaités
   private void addGB(Container cont, Component comp, int x, int y) {
      gbc.gridx = x; gbc.gridy = y;
      cont.add(comp, gbc);
   }

   //methode envoyant un message
   private void sendMessage(String msg) {
      try {
         byte data[] = msg.getBytes(); //transormation en octets
         InetAddress addresse = InetAddress.getByName(destinataire);
         DatagramPacket pack =
           new DatagramPacket(data, data.length, addresse, port);
         DatagramSocket socket = new DatagramSocket();
         socket.send(pack);
         socket.close();
         area.append("\n" + localHost() + " : " + msg);
      }
      catch (UnknownHostException e) {
         JOptionPane.showMessageDialog(frame, "Erreur : impossible de trouver la machine", "Erreur de Connexion", JOptionPane.ERROR_MESSAGE);
         //on demande la saisi d'un autre destinataire
         String passMsg2 = "Saisissez le nom de la machine du destinataire";
         JTextField hostField2 = new JTextField(); 
         hostField2.setText(destinataire);
         int result2 = JOptionPane.showOptionDialog(frame, new Object[] { passMsg2, hostField2 }, "Connexion - destinataire", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
         if(result2 == JOptionPane.OK_OPTION) {
            destinataire = hostField2.getText();
         }
      }
      catch (SocketException e2) {
         JOptionPane.showMessageDialog(frame, "Erreur interne : echec de l'envoi du message", "Erreur de Connexion", JOptionPane.ERROR_MESSAGE);
         System.out.println(e2); //log
      }
      catch (IOException e3) {
          JOptionPane.showMessageDialog(frame, "Erreur interne : echec de l'envoi du message", "Erreur de Connexion", JOptionPane.ERROR_MESSAGE);
         System.out.println(e3); //log
      }
   }

   private void ecouter() {
      try {
         DatagramSocket s =  new DatagramSocket(port);
   //capacité de 2048 caractères
         DatagramPacket pack = 
            new DatagramPacket(new byte[2048], 2048);
         s.receive(pack);
         String message = new String(pack.getData());
         area.append("\n" + pack.getAddress().getHostName() + " : " + message);
      }
      catch (SocketException e4) {
         JOptionPane.showMessageDialog(frame, "Erreur interne : echec de la réception d'un message", "Erreur de Connexion", JOptionPane.ERROR_MESSAGE);
         System.out.println(e4);
      }
      catch (IOException e5) {
          JOptionPane.showMessageDialog(frame, "Erreur interne : echec de la réception d'un message", "Erreur de Connexion", JOptionPane.ERROR_MESSAGE);
         System.out.println(e5);
      }
   }

   public Conversation() {
      area.setEditable(false);
      Container content = frame.getContentPane();
      content.setLayout(new GridLayout(2,1));
      content.add(new JScrollPane(area));
      JPanel panel = new JPanel();
      panel.setLayout(new GridBagLayout());
      gbc.gridwidth = 3;
      addGB(panel, field, 0, 4);
      gbc.gridwidth = 1;
      JButton button;
      button2 = new JButton("Envoyer");
      addGB(panel, button2, 0, 5);
      button2.addActionListener(this);
      addGB(panel, button = new JButton("port ..."), 1, 5);
      button.addActionListener(this);
      addGB(panel, button = new JButton("destinataire ..."), 2, 5);
      button.addActionListener(this);
      content.add(panel);
      thread = new Thread(this);
      thread.start();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setLocation(200, 200);
      frame.pack();
      frame.show();
   }

   public void actionPerformed(ActionEvent e) {
      if(e.getSource() == button2) {
         sendMessage(field.getText());
      }
      else if(e.getActionCommand().equals("port ...")) {
        String portMsg = "Indiquez le port";
        JTextField portField = new JTextField();
        portField.setText(new String(new StringBuffer().append(port)));
        int result = JOptionPane.showOptionDialog(frame, new Object[] { portMsg, portField }, "Connexion - destinataire", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
        if(result == JOptionPane.OK_OPTION) {
           try {
              int newPort = Integer.parseInt(portField.getText());
              if(newPort > 1024)
                 port = newPort;
           }
           catch (Exception pe) { }
        }
      } else if(e.getActionCommand().equals("destinataire ...")) {
         String passMsg = "Saisissez le nom de la machine du destinataire";
         JTextField hostField = new JTextField(); 
         hostField.setText(destinataire);
         int result = JOptionPane.showOptionDialog(frame, new Object[] { passMsg, hostField }, "Connexion - destinataire", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
         if(result == JOptionPane.OK_OPTION) {
            destinataire = hostField.getText();
         }
      }
   }

   public void run() {
      while(true) {
        ecouter();
      }
   }

   public static void main(String args[]) {
      new Conversation();
   }
}

Conclusion :


voila, il suffit de lancer l'application et de spécifier le destinataire et le port, et deux applications situées sur deux ordi différent (avec réseau locale) peuvent communiquée. Testé et compiler avec JSE 1.4.1 et testé sur un réseau locale 10/100 mégabits. J'ai seulement été impressionné de la lenteur de l'application sur portable 1.1 giga hertz et 60 giga de disque dur et paramétré pour de nombreux réseaux locale, ce qui provoquait peut-être la lenteur mais un oridnateur de bureau récent envoye et receptionne preque instantanément les messages

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
91
Date d'inscription
lundi 25 juillet 2005
Statut
Membre
Dernière intervention
18 mai 2010

Bonjour, je n'arrive pas a lancé le fichier.
J'ai procédé a une compilation du fichier par javac puis j'ai essayé de le lancer en faisant java.

Quelqu'un pourrais me dire si ce sont les bonne méthodes ? Car je suis totalement novice et je ne sais plus du tout comment lancer un programme java.

Cordialement,

NeMMo
Messages postés
1
Date d'inscription
jeudi 12 mars 2009
Statut
Membre
Dernière intervention
12 mars 2009

svp vous pouvez envoyez la mise à jour de se programe merci d'avance
Messages postés
6
Date d'inscription
mardi 9 mai 2006
Statut
Membre
Dernière intervention
5 septembre 2006

alors, salut
le pb vient de la fonction ecouter()
dans la fonction run(), il boucle sur ecouter()
le pb, dans la fonction ecouter, il crée un nouveau DataSocket sur le port, la 1ere fois pas de pb, la 2eme fois, il le crée alors qu'il a déjà été crée
solution : fermer le DataSocket a la fin de la fonction ecouter

par contre, la reception de message est assez lente mais je sais encore pourqoi
Messages postés
83
Date d'inscription
jeudi 24 juillet 2003
Statut
Membre
Dernière intervention
16 février 2005

Apparement tu parles d'une version plus récente et corrigée, pourrais tu la mettre en ligne s'il te plaît ?

Je dois avoir la même erreur que patbloup, car à chaque message reçu j'ai une exception du type : java.net.BindException.
En plus on dirai une boucle infinie, mais j'ai tué le processus au bout de 5 ou 6 fois l'erreur car je n'avais pas envie de cliquer 200 fois sur OK.

Merci
Messages postés
1
Date d'inscription
lundi 22 mars 2004
Statut
Membre
Dernière intervention
24 juin 2004

dsl de ne pa vous avoir réponde avant... :( mais bon je ne vient pa souvent sur ce site. charlantant dev-c++ c pour développer en c++ :) pa en java.Et pour patbloup une exception se lève si tu essaye de t'envoyer un msg à toi mm mais normalement le prog marche....
enfin bon si tu veu puiske g réglé ce problème d'ordinateur g une mise a jour si tue veu je te l'envoi tt de suite :)
Afficher les 8 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.