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 envoi pas tous les data


Sujet :

Entrée/Sortie Java

  1. #1
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2012
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2012
    Messages : 149
    Par défaut Socket envoi pas tous les data
    Bonjour à tous,

    alors j'ai fait pour commencer un socket serveur et client,
    le client envoi "e04fd020ea3a6910a2d808002b30309d"
    mais le serveur reçois qu'une partie à savoir "4f203a10d80309d".

    Dois-je mettre un Thread.sleep() quelque part ?

    Serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    public class SocketServer extends Thread
    {
       private ServerSocket serverSocket;
       private String bitS = "";
     
       public SocketServer(int port) throws IOException
       {
          serverSocket = new ServerSocket(port);
          serverSocket.setSoTimeout(1000000);
       }
     
       @Override
       public void run()
       {
          while(true)
          {
             try
             {
                System.out.println("écoute sur le port : " +
                serverSocket.getLocalPort() + "...");
                 try (Socket server = serverSocket.accept()) {
                     System.out.println("connecté à : " + server.getRemoteSocketAddress());
                     DataInputStream in = new DataInputStream(server.getInputStream());
                     //System.out.println(in.readUTF());
                     while(in.readBoolean())
                     {
                        bitS = bitS + Integer.toHexString(in.read()); 
     
                     } 
                     System.out.println(bitS);
                     DataOutputStream out = new DataOutputStream(server.getOutputStream());
                     out.writeUTF("connexion réussie " + server.getLocalSocketAddress() + "\nfin");
                     in.close();
                     out.close();
                 }
             }catch(SocketTimeoutException s)
             {
                System.out.println("temps écoulé");
                break;
             }catch(IOException e)
             {
                 System.out.println("erreur : " + e);
                break;
             }
          }
       }
       public static void main(String [] args)
       {
          int port = 12654;
          try
          {
             Thread t = new SocketServer(port);
             t.start();
          }catch(IOException e)
          {
          }
       }
    }
    Client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    public class Client2 {
     
        public static byte[] hexStringToByte(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                                 + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }
     
        public static void main(String[] args) throws InterruptedException {
              String serverName = "localhost";
          int port = 12654;
          byte[] b = hexStringToByte("e04fd020ea3a6910a2d808002b30309d");
          try
          {
             System.out.println("Connexion à " + serverName + " sur le port " + port);
                try (Socket client = new Socket(serverName, port)) {
                    System.out.println("connecté à : " + client.getRemoteSocketAddress());
                    OutputStream outToServer = client.getOutputStream();
                 try (DataOutputStream out = new DataOutputStream(outToServer)) {
                     out.write(b);
                     out.writeUTF("Salut c'est : " + client.getLocalSocketAddress()+ " le 2e client "
                             + "\n attention j'envoi en byte ^^");
                     InputStream inFromServer = client.getInputStream();
                        try (DataInputStream in = new DataInputStream(inFromServer)) {
                            System.out.println("Réponse du serveur : " + in.readUTF());
                        }
                 }
                }
          }catch(IOException e)
          {
              System.out.println("erreur : " + e);
          }
        }
    }

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 578
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 578
    Par défaut
    Ben tu perds grosso-modo la moitié des données...
    Ce qui est un peu normal puisque tu oscilles entre lire un octet comme booléen et lire un octet comme int, mais que tu ne gardes que le int.
    Garder un octet sur deux => perdre la moitié des données. Logique.

    Ce n'est pas comme ça qu'on boucle sur un DataInputStream. Il faut savoir combien il y a de données à lire et s'arrêter quand on les a toutes lues.

    Mais vu que là tu essaies de lire tous les octets et de les afficher en hexadécimal, pourquoi utiliser DataInputStream et pas simplement InputStream ?

    Citation Envoyé par toufik135 Voir le message
    Dois-je mettre un Thread.sleep() quelque part ?
    Je vois pas le rapport -_-°.
    C'est du TCP, les données sont convoyées correctement ou une IOException est lancée. Pas d'alternative.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    959
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 959
    Par défaut
    Pour apporter une précision, readBoolean ne permet pas de savoir si il reste des données. C'est une méthode qui lit un octet et l'interprète sous forme de booléen.

  4. #4
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2012
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2012
    Messages : 149
    Par défaut
    d'accord mais comment je peux faire alors pour lire les données jusqu'à ce qu'il y en ait plus sans savoir la taille ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while(????)
                        {
                           bitS = bitS + Integer.toHexString(in.read()); 
     
                        }

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 578
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 578
    Par défaut
    Comme je te l'ai déjà dit, avec un DataInputStream tu dois te débrouiller pour le savoir.

    Exemples :
    - le client et le serveur savent tous les deux qu'exactement 40 octets seront envoyés, parce que ça a été décidé comme ça.
    - le message commence par 4 octets qui indiquent la longueur du reste.

    Donc comme je te l'ai déjà dit, pour ce que tu essaies d'en faire, il faut un InputStream et pas un DataInputStream.

    Edit : je constate que la FAQ ne dit pas vraiment comment faire avec un InputStream.

    Voici la méthode naïve mais pas très efficace :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int b = in.read();
    while(b >= 0) {
      bitS = bitS + String.format("%02x", (byte)b); 
      b = in.read();
    }
    Et la méthode bufferisée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    byte[] buffer = new byte[1024];
    int nbRead = in.read(buffer);
    while(nbRead >= 0) {
      for(int i = 0; i < nbRead; i++) {
        bitS = bitS + String.format("%02x", buffer[i]); 
      }
      nbRead = in.read(buffer);
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2012
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2012
    Messages : 149
    Par défaut
    Désolé, j'ai peut-être mal compris mais j'ai testé la solution de cette manière :
    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
     
    public void run()
       {
          while(true)
          {
             try
             {
                 System.out.println("écoute sur le port : " +
                 serverSocket.getLocalPort() + "...");
                 Socket server = serverSocket.accept();
                 System.out.println("connecté à : " + server.getRemoteSocketAddress());
                 DataOutputStream out;
                 InputStream in = server.getInputStream();
                 byte[] buffer = new byte[1024];
                 int nbRead = in.read(buffer);
                 while(nbRead >= 0) {
                   for(int i = 0; i < nbRead; i++) {
                      bitS = bitS + String.format("%02x", buffer[i]); 
                   }
                   nbRead = in.read(buffer);
                }
                System.out.println(bitS);
                out = new DataOutputStream(server.getOutputStream());
                out.writeUTF("connexion réussie " + server.getLocalSocketAddress() + "\nfin");
     
                out.close();
             }catch(SocketTimeoutException s)
             {
                System.out.println("temps écoulé");
                break;
             }catch(IOException e)
             {
                 System.out.println("erreur : " + e);
                break;
             }
          }
       }
    mais il se connecte et reste en boucle sans rien recevoir.

  7. #7
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 578
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 578
    Par défaut
    Effectivement, je vois que le serveur est censé donner une réponse quand il a fini de lire tous les octets... C'est-à-dire quand la socket est fermée et qu'il n'est plus possible d'envoyer une réponse -_-° ! Cela n'arrive donc bien sûr jamais.

    C'est la quadrature du cercle. Si tu veux que le serveur envoie une réponse après avoir lu le message, il est obligatoire qu'il sache quelle est la taille du message.
    Si tu veux lire jusqu'à ce qu'il n'y ait plus rien à lire sans t'occuper de taille, alors tu ne peux pas envoyer de réponse.

    Le plus simple est de revenir sur un DataInputStream et d'indiquer juste la taille du premier message avant de l'envoyer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    out.writeInt(b.length);
    Et de l'autre côté, lire cette taille; et s'en servir pour la boucle de lecture d'octets, puis lire la String qui était envoyée avec writeUTF :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // lire les octets
    int messageSize = in.readInt();
    byte[] message = new byte[messageSize];
    in.readFully(message);
    for(int i = 0; i < messageSize; i++) {
      bitS = bitS + String.format("%02x", message[i]);
    }
     
    // lire la String
    String string = in.readUTF();
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre confirmé
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2012
    Messages
    149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2012
    Messages : 149
    Par défaut
    merci

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

Discussions similaires

  1. Jointure qui ne renvoie pas tous les enregistrements
    Par rayonx dans le forum Langage SQL
    Réponses: 12
    Dernier message: 19/07/2024, 09h33
  2. [Postfix] mon adresse n'envoie pas tous les mails
    Par stc074 dans le forum Debian
    Réponses: 1
    Dernier message: 04/06/2015, 12h16
  3. MoveWindow n'envoie pas tous les messages
    Par d'Oursse dans le forum Windows
    Réponses: 0
    Dernier message: 20/10/2007, 20h30
  4. Les Langages ne sont pas tous les mêmes ......
    Par Max Payne dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 28/08/2003, 13h51

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