Erreur sur read et readLine sur un Socket

Résolu
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009 - 30 juil. 2008 à 15:52
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009 - 30 juil. 2008 à 19:00
Bonjour, j'essaye actuellement de bricoler en Java (je débute) les sockets et la connection inter-programmes, pour le plaisir. Seulement si j'arrive à faire de connecter un serveur et un ou plusieurs clients, je n'arrive pas à faire passer d'informations entre eux.
Je suis donc revenu à un code ultra simplifié côté serveur comme côté client pour voir d'où venait le problème. Ici je me contente donc d'établir la connection puis d'envoyer un caractère o`|u une chaîne de caractères côté client, et de le réceptinoner avec read ou readLine (y compris la version de read qui utilise un tableau de caractères) côté serveur, en attendant réception une fois la connection établie côté serveur. Je me suis ainsi aperçu que c'était la fonction de lecture qui renvoyait une exception sur le serveur, et ce même si le client n'envoyait rien de son côté. Simplement une fois la connectino établie, quand le serveur passe à l'instruction read ou readLine, il sort une exception. Voici mon cide pour observation, je vous serais reconnaissant si vous pouviez m'apporter quelque lumière sur la question.
(Pour info j'ai essayé sur les ports 1800 et 18000, et ce qui est  en commentaire dans le code du serveur est la boucle que j'avais prévue à l'origine avant de simplifier encore le code.)

Serveur :

import java.net.*;
import java.io.*;
import java.util.*;

public class serveur
{
public static void main(String args[])
  {
  try
    {
    ServerSocket ss = new ServerSocket(1800);
    while (true)
      {
      Socket _s = ss.accept();
      System.out.println("Un client se connecte.");
      BufferedReader _in = new BufferedReader(new InputStreamReader(_s.getInputStream()));
      char[] message = new char[10];
      _in.read(message);
    /*while ((message = _in.read())!= 100)  (A ce moment, message était de type char)
        {
         System.out.println("un message passe");
         System.out.write(message);
         }      */
      }
    }
  catch (Exception e)
    {
    System.out.println("Une erreur est survenue.");
    }
  }
}

Client :

import java.net.*;
import java.io.*;
import java.util.*;

public class client
  {
  public static void main(String[] argv)
    {
    BlablaClient client = new BlablaClient();
    try
      {
      Socket _s = new Socket("localhost", 1800);
      PrintWriter _out = new PrintWriter (new OutputStreamWriter(_s.getOutputStream()));
      System.out.println("un message est envoye");
      _out.print("Ceci est un message du client.");
      }
    catch (Exception e)
      {
      System.out.println("Une erreur est survenue.");
      }
    }
  }

Nitruk

15 réponses

cs_Kysic Messages postés 332 Date d'inscription mardi 12 juillet 2005 Statut Membre Dernière intervention 17 juillet 2010
30 juil. 2008 à 18:04
Essaie avec le code suivant, si ça ne marche pas il faut chercher ailleurs que dans le code (genre pare feu, mais j'en doute).
Je penses que ton "new PrintWriter (new OutputStreamWriter)" pose problème.
Avec les flux il faut être symétrique, si on écrit des bytes on lit des bytes, si on écrit des lignes on lit des lignes.
Pour l'erreur que tu as indiqué, elle indique simplement que la socket a été fermée avant que la lecture soit faite, ce qui aurait été intéressant c'est l'erreur côté client.

Client :
import java.net.*;
import java.io.*;
import java.util.*;


public class client
{
public static void main(String[] argv)
{
try
{
Socket _s = new Socket("localhost", 1800);
PrintStream _out = new PrintStream(_s.getOutputStream());
System.out.println("un message est envoye");
_out.println("Ceci est un message du client.");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

Serveur:

import java.net.*;
import java.io.*;
import java.util.*;

public class serveur
{
public static void main(String args[])
{
try
{
ServerSocket ss = new ServerSocket(1800);
while (true)
{
Socket _s = ss.accept();
System.out.println("Un client se connecte.");
BufferedReader _in = new BufferedReader(new InputStreamReader(_s.getInputStream()));
System.out.println( _in.readLine() );
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
3
cs_Kysic Messages postés 332 Date d'inscription mardi 12 juillet 2005 Statut Membre Dernière intervention 17 juillet 2010
30 juil. 2008 à 16:24
Salut,
personnellement j'utilise :

Réception message :
br = new BufferedReader(new InputStreamReader(soc.getInputStream()));
String rep = br.readLine();

Envoi message :
ps = new PrintStream(soc.getOutputStream());
ps.println("Essai");

Cordialement
0
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009
30 juil. 2008 à 17:01
Merci d'avoir répondu si vite :)
Comme je le disais plsu haut, j'ai essayé avec read et readLine, et côté client avec write et println.
En tout ca sc'est du côté de la réception que ça bloque, même si le client n'evoie rien (je le fais quand même se connecter pour avoir un socket duquel tenter une réception).

Nitruk
0
cs_Kysic Messages postés 332 Date d'inscription mardi 12 juillet 2005 Statut Membre Dernière intervention 17 juillet 2010
30 juil. 2008 à 17:11
Pourrais tu nous donner l'exception générée stp.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Kysic Messages postés 332 Date d'inscription mardi 12 juillet 2005 Statut Membre Dernière intervention 17 juillet 2010
30 juil. 2008 à 17:16
A mon avis le problème est ton "_out.print("Ceci est un message du client.");" et si tu as une exception quand tu n'écris rien s'est normal, c'est que le client ferme la socket, donc le serveur n'a plus rien à attendre de lire dessus.
0
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009
30 juil. 2008 à 17:23
Comme je vous le disais je suis débutant, et je ne maîtrise pas trop les exceptions, et encore moins celles qui concernent les Sockets et les lectures et écritures. Je vais me renseigner sur le sujet. Et effectivement je devrais avoir println, mais je ne pense pas que ce soit ça puisque comme je le disais j'ai essayé avec plusieurs foncitons d'écriture, avec des chaînes ou des caractères, donc ce print n'a pas toujours été là.Enfin je vais essayer ça, et aussi de maintenir le client connecté sans envoyer de message.

Nitruk
0
cs_Kysic Messages postés 332 Date d'inscription mardi 12 juillet 2005 Statut Membre Dernière intervention 17 juillet 2010
30 juil. 2008 à 17:28
En fait pour connaître l'exception générée il suffit de rajouter un "e.printStackTrace()" dans tes blocs "catch (Exception e)".
0
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009
30 juil. 2008 à 17:37
Bon, j'ai essayé en changeant print par println, sans observer de changement. Par contre, quand j'ai collé une boucle infinie avant l'expédition du message côté client, il n'y a plus eu d'exception déclenchée chez le serveur, ce qui prouve que vous aviez raison (A savoir :  c'est la fermeture du socket par le client qui cause l'erreur si aucun message n'est envoyé, et donc dans le cas contraire c'est bien àa la réception du message qu'il y a erreur. Je vais chercher le détail des exceptions.

Nitruk
0
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009
30 juil. 2008 à 17:40
java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(SocketInputStream.java:168)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
        at java.io.InputStreamReader.read(InputStreamReader.java:167)
        at java.io.BufferedReader.fill(BufferedReader.java:136)
        at java.io.BufferedReader.read1(BufferedReader.java:187)
        at java.io.BufferedReader.read(BufferedReader.java:261)
        at java.io.Reader.read(Reader.java:123)
        at serveur.main(serveur.java:16)

Donc une remise à 0 de la connection, apparement. Personnellement je ne m'y connais aps assez pour que ça puisse m'éclairer sur ce qui arrive et ce que je dois changer.

Nitruk
0
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009
30 juil. 2008 à 17:43
J'ai essayé en collant la boucle infinie après l'envoi du message, pour voir. Et là j'ai pu constater que l'erreur n'aparaissait pas avant que je ferme le client. Il semble donc que le serveur ne trouve pas la fin du message et continue à attendre jusqu'à ce que la connexion soit fermée. Pourtant j'ai bien println et readLine...

Nitruk
0
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009
30 juil. 2008 à 17:47
Juste pour info, j'ai essayé d'ajouter \r\n à la fin du message, sans résultat.





Nitruk
0
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009
30 juil. 2008 à 17:56
Avec read pas plus qu'avec readLine on n'aq de résultat, or read se contente du 1er caractère venu. Plutôt que de ne pas voir la fin du message, le serveur ne verrait donc pas du tout le message venir. Y aurait-il un problème sur l'envoi du côté du client ?
(Je remets le code de celui-ci dans son état actuel.)

import java.net.*;
import java.io.*;
import java.util.*;

public class client
  {
  public static void main(String[] argv)
    {
    BlablaClient client = new BlablaClient();
     try
      {
      Socket _s = new Socket("localhost", 1800);
      PrintWriter _out = new PrintWriter (new OutputStreamWriter(_s.getOutputStream()));
      System.out.println("un message est envoye");
      _out.println("Ceci est un message du client.\r\n");
      int essai;
      while(true)
        {
        essai = 1;
        }
      }
    catch (Exception e)
      {
      System.out.println("Une erreur est survenue.");
      e.printStackTrace();
      }
    }
  }

Nitruk
0
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009
30 juil. 2008 à 18:52
Pour l'erreur j'avais bien compris, ce que je cherchais c'est pourquoi mes messages n'étaient pas reçus avant la fermeture. Et il n'y a aps d'erreur du côté du client, qui se content d'envoyer ses messages sans se soucier qu'ils soient lus.
En tout cas je vous doit un grand merci pour vos réponses et pour l'aide apportée, d'autant plus qu'effectivement le PrintStream permet de résoudre le problème.  La documentation à laquelle je me référais ne parlait pas de ce flux de sortie, et je serais curieux de savoir quelle est la différence avec un PrintWriter, et quel serait alors le "symétrique" de ce dernier
du côté de la réception.
Nitruk
0
cs_Kysic Messages postés 332 Date d'inscription mardi 12 juillet 2005 Statut Membre Dernière intervention 17 juillet 2010
30 juil. 2008 à 18:57
On peut aussi utiliser un PrintWriter mais alors il faut faire:

fluxentrant = new BufferedReader(new InputStreamReader(soc.getInputStream()));

fluxsortant = new PrintWriter(new BufferedWriter(new OutputStreamWriter(soc.getOutputStream())), true);

et c'est un peu lourd (à écrire).
Sinon pour le print j'ai du dire un connerie.
0
Nitruk Messages postés 128 Date d'inscription lundi 8 août 2005 Statut Membre Dernière intervention 20 juillet 2009
30 juil. 2008 à 19:00
Donc ce qu'il faut c'est qu'il y ait un Buffer des 2 côté ? Et le PrintStream possède donc par lui-même un tampon ?

Nitruk
0
Rejoignez-nous