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] Simple envoie d'entiers


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 121
    Par défaut [Socket] Simple envoie d'entiers
    Bonjour à tous,

    En vue de faire un jeu simple en réseau, j'essai de réaliser un échange d'entier en utilisant les sockets.

    Hélas mon programme ne marche pas correctement.
    En théorie, le serveur doit envoyer un entier entré au clavier par l'utilisateur, puis lire un entier que lui envoie le client. Cette séquence s'effectue 5 fois de suite.

    Le problème est qu'après avoir entré le premier entier au clavier coté serveur, le client agit comme s'il avait reçu 2 entiers.

    Voici les deux classes :

    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
    import java.net.*;
     
    public class Server {
       static final int port = 8080;
     
       public static void main(String[] args) throws Exception {
     
           ServerSocket Ssoc = new ServerSocket(port);
           System.out.println("Server : Attente de connexion");
     
           Socket Csoc = Ssoc.accept();
           System.out.println("Server : Connexion établie");
     
           InputStream  IS = Csoc.getInputStream();
           OutputStream OS = Csoc.getOutputStream();
     
           DataOutputStream DOS = new DataOutputStream(OS);
           DataInputStream DIS = new DataInputStream(IS);
     
            InputStreamReader isr=new InputStreamReader(System.in);
            BufferedReader br=new BufferedReader(isr);
     
           for(int i=0 ; i<5 ; i++){
                System.out.println("Server : Quel entier souhaitez-vous envoyer ?");
                DOS.writeInt(br.read());
                DOS.flush();
                System.out.println("Server : Entier reçu : "+ DIS.readInt());
           }
           Ssoc.close();
       }    
    }
    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
    package applettest;
     
    import java.io.*;
    import java.net.*;
    public class Client {
       static final int port = 8080;
     
       public static void main(String[] args) throws Exception {
     
             Socket soc = new Socket("192.168.6.107", port);
     
             InputStream IS = soc.getInputStream();
             OutputStream OS = soc.getOutputStream();
     
             DataOutputStream DOS = new DataOutputStream(OS);
             DataInputStream DIS = new DataInputStream(IS);
     
             for(int i=0 ; i<5 ; i++){
                 System.out.println("Client : Entier reçu : "+DIS.readInt());
                 DOS.writeInt(666);
                 DOS.flush();
     
             }
             soc.close();
       }
    }

    Voici ce que donne les sorties :

    Coté 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
    Server : Attente de connexion
    Server : Connexion établie
    Server : Quel entier souhaitez-vous envoyer ?
    2
    Server : Entier reçu : 666
    Server : Quel entier souhaitez-vous envoyer ?
    Server : Entier reçu : 666
    Server : Quel entier souhaitez-vous envoyer ?
    1
    Server : Entier reçu : 666
    Server : Quel entier souhaitez-vous envoyer ?
    Server : Entier reçu : 666
    Server : Quel entier souhaitez-vous envoyer ?
    2
    Server : Entier reçu : 666
    Coté client :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Client : Entier reçu : 50
    Client : Entier reçu : 10
    Client : Entier reçu : 49
    Client : Entier reçu : 10
    Client : Entier reçu : 50

    Ca ressemble à une erreur de tampon mal vidé, mais je ne vois pas trop comment le résoudre (si c'est bien cela).


    Une petite idée ?

  2. #2
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    salut,

    Server : Quel entier souhaitez-vous envoyer ?
    2
    Server : Entier reçu : 666
    Server : Quel entier souhaitez-vous envoyer ?
    Server : Entier reçu : 666
    Server : Quel entier souhaitez-vous envoyer ?
    d'après ton log, tu entre une seule fois un entier sur l'entrée standard et tu passes deux fois par le println("Server : Entier reçu : ");

    Or si tu passes deux fois par cette ligne, ça veut forcément dire que tu est passé juste avant deux fois par br.read() qui avait donc des choses à lire non pas une mais deux fois !

    Ensuite, on regarde ce que le client a reçu: quand tu as tapé le chiffre '2', br.read() a pu lire successivement 50 et 10. Quand tu as tapé le chiffre '1', tu as reçu 49 et 10.

    Tiens, '2' => 49, '1' => 50 ? ça ressemblerait pas à la valeur ASCII des caractères '2' et '1' ?

    Reste la valeur 10 qu'on reçoit à chaque fois en trop ? Se pourrait-il que ce soit également un caractère ASCII ? Je sais pas, moi, qu'est ce que tu as bien pu taper également ? un retour chariot par hasard ?

    Euréka!

    br.read() ne lit pas une valeur entière fournie par l'utilisateur sous forme de texte, mais plutôt des valeurs ASCII, caractère par caractère, finalement ni plus ni moins ... que ce que la javadoc stipule pour la fonction BufferedReader::read()

    Dans ton cas, il me semblerait plus approprié de faire usage de la fonction BufferedReader::readLine() pour récupérer un String que tu pourras ensuite convertir en valeur numérique à l'aide de la fonction statique Integer.parseInt() (modulo les exceptions à chopper quand il faut):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DOS.writeInt( Integer.parseInt(br.readLine()) );

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 121
    Par défaut
    Rapide et efficace merci bien !

    Effectivement j'avais remarqué que j'obtenais des valeurs qui tournaient autour de 50 mais je n'avais pas fait le lien avec la table ASCII !

    Bon ben j'y retourne

  4. #4
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par nouknouk Voir le message
    Tiens, '2' => 49, '1' => 50 ? ça ressemblerait pas à la valeur ASCII des caractères '2' et '1' ?
    Pour être tout à fait exact:

    La valeur numérique du caractère retournée par BufferedReader.read() n'est pas sa valeur en ASCII mais celle en UTF-8.
    Mais dans ton exemple précis, les caractères ont tous des valeurs inférieures à 127, et dans ce cas là, les charsets UTF-8 et ASCII sont identiques.

    Pour t'en convaincre, tu peux toujours essayer de réutiliser ton code du dessus et taper le symbole '€' (euro) pour voir ce qu'il te retourne (normalement 8364).

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

Discussions similaires

  1. Socket et envoi d'image
    Par kheldoun ahmed dans le forum Delphi
    Réponses: 2
    Dernier message: 31/07/2007, 15h32
  2. simple calcul d'entier
    Par gadalla dans le forum Langage
    Réponses: 4
    Dernier message: 10/07/2007, 14h10
  3. Socket 2 envoi = 1 arrivée ?
    Par Aleksis dans le forum C++
    Réponses: 7
    Dernier message: 22/08/2006, 17h58
  4. windows socket, problème envoi de structure :s
    Par ramislebob dans le forum Réseau
    Réponses: 7
    Dernier message: 29/07/2006, 23h17
  5. [Socket] Probleme envois de message
    Par Pierrick584 dans le forum C++
    Réponses: 12
    Dernier message: 28/06/2006, 19h07

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