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 :

Créer un Client UDP avec description du protocole


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 1
    Par défaut Créer un Client UDP avec description du protocole
    Bonjour,

    j'aimerai développer un client java pour envoyer des requetes sur un server.
    Le problème c'est que je suis pas à l'aise avec la communication client-server.

    Serait_il possible de m'aider pour faire le début ? juste le packet pour se loguer
    la description du protocole est ici :
    http://www.battleye.com/downloads/BERConProtocol.txt

    j'ai récupéré un squelette de client udp sur le net :

    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
     
    import java.io.*;
    import java.net.*;
    import java.util.*;
     
    public class ClientUDP {
        public static void main(String[] argv) throws IOException {
            int port;
     
    		if (argv.length != 2) {
                 System.out.println("Usage: java Client <nom machine> <num port>");
                 return;
    		}
    		try {
                port = Integer.parseInt(argv[1]);
            } catch (NumberFormatException e) {
                System.out.println("le numéro de port : "+ argv[1] +" doit être un entier");
                return;
            }
    		DatagramSocket socket = new DatagramSocket();
     
    		// envoie 
            byte[] buf = new byte[256];
            InetAddress adr = InetAddress.getByName(argv[0]);
            DatagramPacket packet = new DatagramPacket(buf, buf.length, adr, port);
            socket.send(packet);
     
    		// Envoie password
                    //  ???
     
    		// Recuperation reponse
    		String received;
            buf = new byte[256];
            packet = new DatagramPacket(buf, buf.length);
            socket.receive(packet);
     
            received = new String(packet.getData());
            System.out.println(received);
     
    		// fin
            socket.close();
            System.exit(0);
        }
    }
    Merci à vous.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    pour réaliser le client udp correspondant à la description, il suffit de lire cette description :
    - tu identifies chaque message
    - le principe est de représenter au final chaque message envoyé par un tableau d'octets (perso je ferais un modèle de classes...)

    regarde cette partie de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    byte[] buf = new byte[256];
            InetAddress adr = InetAddress.getByName(argv[0]);
            DatagramPacket packet = new DatagramPacket(buf, buf.length, adr, port);
    ici buf est le tableau d'octets qui doit contenir le message envoyé.

    par exemple, dans la description, on a le message de login sous la forme
    0x00 | password (ASCII string without null-terminator)

    pas de fin de message, je suppose que la taille du message est utilisée, donc il te faudra passer la taille du message, soit celle du password, + 1 octet de type + 7 octets d'entête (décrite au tout début) , à la place de buf.length


    de même :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    String received;
            buf = new byte[256];
            packet = new DatagramPacket(buf, buf.length);
            socket.receive(packet);
     
            received = new String(packet.getData());
    et la partie reception

    au lieu de convertir en chaine packet.getData(), lit directement le tableau d'octets (j'utiliserais aussi un modèle de classes pour décoder) :

    pour le login,

    0x00 | (0x01 (successfully logged in) OR 0x00 (failed))

    donc on aurait un tableau de 9 octets, si on compte pas l'entête, 2 octets, avec 0 pour le premier, et 1 ou 0 pour le second, pour connaitre le résultat du login
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Pour commencer ton modèle de classes, voici en exemple l'abstraction dont toutes tes classes de message (à envoyer en tout cas) pourront hériter :

    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.util.zip.CRC32;
    import java.util.zip.Checksum;
     
     
    public abstract class AbstractBeRConMessage {
     
    	public final static int HEADER_LENGTH=7;
    	public final static byte TYPE_LOGIN=0x00;
    	public final static byte TYPE_COMMAND=0x01;
    	public final static byte TYPE_SERVER=0x02;
     
    	private final byte type;
     
    	public AbstractBeRConMessage(byte type) {
    		this.type=type;
    	}
     
    	public final byte getType() {
    		return type;
    	}
     
    	public final int fill(byte[] bytes) {
    		fillHeader(bytes);
    		fillType(bytes);
    		int size = fillMessage(bytes, HEADER_LENGTH+1);
    		setChecksum(bytes, size);
    		return size+HEADER_LENGTH+1; // + 1 pour l'octet de type
    	}
     
    	private void fillType(byte[] bytes) {
    		bytes[HEADER_LENGTH+1]=type;
    	}
     
    	private void setChecksum(byte[] bytes, int size) {
     
    		// calcul du crc32 du message
    		Checksum checksum = new CRC32();
    		checksum.update(bytes,HEADER_LENGTH,size);
    		long value = checksum.getValue();
     
    		// on met le checksum dans les octets de 2 à 5
    		bytes[2] = (byte) ((value & 0xFF000000) >> 3);
    		bytes[3] = (byte) ((value & 0xFF0000) >> 2);
    		bytes[4] = (byte) ((value & 0xFF00) >> 1);
    		bytes[5] = (byte) (value & 0xFF) ;
     
    	}
     
    	private void fillHeader(byte[] bytes) {
    		// 'B'(0x42) | 'E'(0x45) | 4-byte CRC32 checksum of the subsequent bytes | 0xFF
    		bytes[0]=0x42;
    		bytes[1]=0x45;
    		bytes[6]=(byte) 0xFF;
    	}
     
    	/**
             * remplit le tableau d'octets avec les données du message</p>
             * le premier octet du message doit commencer à l'offset passé en argument
             * @param bytes
             * @param offset 
             * @return
             */
    	protected abstract int fillMessage(byte[] bytes, int offset);
     
    }
    et un exemple pour le message de password :

    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
     
    public class LoginPacket extends AbstractBeRConMessage {
     
    	private String password;
     
    	public LoginPacket() {
    		super(TYPE_LOGIN);
    	}
     
    	public LoginPacket(String password) {
    		this();
    		this.password=password;
    	}
     
    	public void setPassword(String password) {
    		this.password = password;
    	}
     
    	public String getPassword() {
    		return password;
    	}
     
    	@Override
    	protected int fillMessage(byte[] bytes, int offset) {
    		for(int i=0; i<password.length(); i++ ) {
    			char c=password.charAt(i);
    			// on vérifie que le caractère est ASCII
    			if ( c>=0 && c<=127 ) {
    				bytes[offset+i]=(byte) c;
    			}
    			else {
    				throw new IllegalArgumentException("Not ASCII char: "+c);
    			}
    		}
    		return password.length();
    	}
     
    }
    succintement dans ton code pour se loguer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    LoginPacket loginPacket=new LoginPacket("toto");
    int length = loginpacket.fill(buf);
    DatagramPacket packet = new DatagramPacket(buf, length, adr, port);
    socket.send(packet);
    à noter que buf peut être réutilisé pour tous les messages (c'est préférable même), ainsi que l'instance de LoginPacket ( setPassword(...)) ) si tu veux
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

Discussions similaires

  1. Créer un client FTP avec Android
    Par marwwwwwa dans le forum Android
    Réponses: 3
    Dernier message: 24/04/2013, 13h46
  2. Réponses: 3
    Dernier message: 30/08/2011, 09h24
  3. Client Webdav avec le protocol https
    Par jsd03 dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 03/10/2008, 09h19
  4. Réponses: 2
    Dernier message: 22/02/2006, 17h41
  5. Serveur/Client UDP: comment envoyer un fichier avec mon code
    Par danje dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 21/12/2005, 14h54

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